You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
structure() raises StructureHandlerNotFoundError for real InitializeResult with notebookDocumentSync (NotebookDocumentFilterWithCells.notebook union) #462
converter.structure(...) raises StructureHandlerNotFoundError when structuring a real InitializeResult whose capabilities.notebookDocumentSync.notebookSelector contains an entry with only cells (no notebook key) — i.e. the legal "cells-only" NotebookDocumentFilterWithCells shape. Captured verbatim from a real server (ty server, Astral's Python language server) but doesn't depend on it — reproduces with just lsprotocol + cattrs:
cattrs.errors.StructureHandlerNotFoundError: Unsupported type: str | lsprotocol.types.NotebookDocumentFilterNotebookType | lsprotocol.types.NotebookDocumentFilterScheme | lsprotocol.types.NotebookDocumentFilterPattern | None. Register a structure hook for it.
Structuring typing.Sequence[lsprotocol.types.NotebookDocumentFilterWithNotebook | lsprotocol.types.NotebookDocumentFilterWithCells] @ index 0
cattrs can't find/build a structure hook for NotebookDocumentFilterWithCells.notebook's declared union type even though the input omits that key entirely (so the field should just take its default). Every InitializeResponse a server advertises notebookDocumentSync capabilities in — regardless of whether the client cares about notebooks at all — currently fails to structure.
For anyone triaging: this looks related to #259 but isn't a duplicate. #259 was about disambiguating the outer union — which NotebookDocumentSyncOptions.notebookSelector[i] variant a given entry is (NotebookDocumentFilterWithNotebook vs NotebookDocumentFilterWithCells) — fixed via a custom dispatch hook in 2023, and that part does work correctly today: the traceback above shows cattrs correctly resolving to NotebookDocumentFilterWithCells.
The failure here is one level deeper: once inside NotebookDocumentFilterWithCells, its optional notebook field has its own union type (str | NotebookDocumentFilterNotebookType | NotebookDocumentFilterScheme | NotebookDocumentFilterPattern | None), and that union has no structure hook registered at all — even though the field is simply absent from the input and should resolve to None. Different error class too: #259 raised ValueError: has no usable unique attributes from the disambiguator; this raises StructureHandlerNotFoundError for a field-level union with no hook.
So the 2023 fix covered the outer selector-list case but the nested notebook field's union seems to have been missed.
Activity
vivainio commentedon Aug 8, 2026
For anyone triaging: this looks related to #259 but isn't a duplicate. #259 was about disambiguating the outer union — which
NotebookDocumentSyncOptions.notebookSelector[i]variant a given entry is (NotebookDocumentFilterWithNotebookvsNotebookDocumentFilterWithCells) — fixed via a custom dispatch hook in 2023, and that part does work correctly today: the traceback above shows cattrs correctly resolving toNotebookDocumentFilterWithCells.The failure here is one level deeper: once inside
NotebookDocumentFilterWithCells, its optionalnotebookfield has its own union type (str | NotebookDocumentFilterNotebookType | NotebookDocumentFilterScheme | NotebookDocumentFilterPattern | None), and that union has no structure hook registered at all — even though the field is simply absent from the input and should resolve toNone. Different error class too: #259 raisedValueError: has no usable unique attributesfrom the disambiguator; this raisesStructureHandlerNotFoundErrorfor a field-level union with no hook.So the 2023 fix covered the outer selector-list case but the nested
notebookfield's union seems to have been missed.