astral-sh/ruff · error

Text document path does not point to a text document

Error message

Text document path does not point to a text document

What it means

On textDocument/didChange, the document key in the server's index resolved to a notebook document (or non-text entry), so as_text_mut() returned None and the handler bailed (session.rs:1825). The server routes by key: sending the plain text-document notification for something stored as a notebook triggers it.

Source

Thrown at crates/ty_server/src/session.rs:1825

    pub(crate) fn is_cell_or_notebook(&self) -> bool {
        matches!(self, Self::Cell { .. } | Self::Notebook { .. })
    }

    pub(crate) fn update_text_document(
        &mut self,
        session: &mut Session,
        content_changes: Vec<TextDocumentContentChangeEvent>,
        new_version: DocumentVersion,
    ) -> crate::Result<()> {
        let position_encoding = session.position_encoding();
        {
            let mut index = session.index_mut();

            let document_mut = index.document_mut(&self.key())?;

            let Some(document) = document_mut.as_text_mut() else {
                anyhow::bail!("Text document path does not point to a text document");
            };

            if content_changes.is_empty() {
                document.update_version(new_version);
            } else {
                document.apply_changes(content_changes, new_version, position_encoding);
            }

            self.set_version(document.version());
        }

        self.update_in_db(session);

        Ok(())
    }

    pub(crate) fn update_notebook_document(
        &mut self,

View on GitHub (pinned to 672bb4edf0)

Solutions

  1. Use the notebook protocol for notebooks: didOpenNotebookDocument/didChangeNotebookDocument plus cell notifications in the correct order
  2. Ensure the same cell URI is not first opened via plain didOpen
  3. Reopen the notebook in the editor to resynchronize document state

Example fix

// before: notebook doc sent through the text-document flow
notify('textDocument/didChange', { textDocument: { uri: cellUri, version }, ... });

// after: go through the notebook flow
notify('notebookDocument/didChange', {
  notebookDocument: { uri: notebookUri, version },
  change: { cells: { structure, data, textContent } },
});
Defensive patterns

Strategy: type-guard

Validate before calling

// TS: route changes by whether the doc belongs to a notebook
const isNotebookDoc = (uri: vscode.Uri): boolean =>
  !!vscode.workspace.notebookDocuments.some(nb =>
    nb.uri.toString() === uri.toString() ||
    nb.getCells().some(c => c.document.uri.toString() === uri.toString()));

if (isNotebookDoc(doc.uri)) {
  // use notebookDocument/didChange for the parent notebook
} else {
  client.notify('textDocument/didChange', params);
}

Type guard

const isNotebookCell = (uri: string): boolean =>
  vscode.workspace.notebookDocuments.some(nb =>
    nb.getCells().some(c => c.document.uri.toString() === uri));

Prevention

When it happens

Trigger: Sending textDocument/didChange for a notebook document or a URI stored under the notebook namespace — e.g. a client that only implements half of the notebook protocol, or cell URIs reused across didOpen/didOpenNotebookDocument flows.

Common situations: Editors or extensions that open notebook cells as plain text documents after the notebook was registered, partial notebook support in custom clients, or out-of-order open notifications during notebook load.

Related errors


AI-assisted analysis of astral-sh/ruff@672bb4edf0 (2026-08-16). Data as JSON: /api/errors/e8b4b46e54164716. Report an issue: GitHub.