{"record":{"id":"1dc11b799f729310","repo":"astral-sh/ruff","slug":"notebook-document-uri-does-not-point-to-a-notebook","errorCode":null,"errorMessage":"Notebook document URI does not point to a notebook document","messagePattern":"Notebook document URI does not point to a notebook document","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/ruff_server/src/session/index.rs","lineNumber":168,"sourceCode":"        if let Some(lsp_types::NotebookDocumentCellChangeStructure {\n            did_open: Some(did_open),\n            ..\n        }) = cells.as_ref().and_then(|cells| cells.structure.as_ref())\n        {\n            let Some(path) = self.uri_for_key(key).cloned() else {\n                anyhow::bail!(\"Tried to open unavailable document `{key}`\");\n            };\n\n            for opened_cell in did_open {\n                self.notebook_cells\n                    .insert(opened_cell.uri.clone(), path.clone());\n            }\n            // deleted notebook cells are closed via textDocument/didClose - we don't close them here.\n        }\n\n        let controller = self.document_controller_for_key(key)?;\n        let Some(notebook) = controller.as_notebook_mut() else {\n            anyhow::bail!(\"Notebook document URI does not point to a notebook document\");\n        };\n\n        notebook.update(cells, metadata, new_version, encoding)?;\n        Ok(())\n    }\n\n    pub(super) fn open_workspace_folder(\n        &mut self,\n        uri: Uri,\n        global: &GlobalClientSettings,\n        client: &Client,\n    ) -> crate::Result<()> {\n        // TODO(jane): Find a way for workspace client settings to be added or changed dynamically.\n        self.settings\n            .register_workspace(&Workspace::new(uri), global, client)\n    }\n\n    pub(super) fn close_workspace_folder(&mut self, workspace_uri: &Uri) -> crate::Result<()> {","sourceCodeStart":150,"sourceCodeEnd":186,"githubUrl":"https://github.com/astral-sh/ruff/blob/26f38c119cac42e4d320ba08f09224fdec74af2c/crates/ruff_server/src/session/index.rs#L150-L186","documentation":"After handling cell-structure events, `update_notebook_document` fetches the document controller and expects it to hold a notebook. If the controller's document is a plain text document instead, the notebook update cannot be applied and the server bails. It mirrors error 81 for the notebook direction.","triggerScenarios":"Calling `session.update_notebook_document(key, cells, metadata, new_version, encoding)` where the key resolves to a controller holding a text document, so `as_notebook_mut()` returns None.","commonSituations":"A client sends `notebookDocument/didChange` for a URI that was opened as a regular text file via `textDocument/didOpen`; conflicting open events for the same URI across editors/plugins.","solutions":["Send `textDocument/didChange` for plain text documents instead of notebookDocument/didChange","Close the document with the correct (text) lifecycle, then reopen it as a notebook via notebookDocument/didOpen","Restart the Ruff server to clear the mismatched document index"],"exampleFix":null,"handlingStrategy":"validation","validationCode":"// only route notebookDocument/didChange to URIs opened as notebooks\nif (!openedAsNotebook.has(uri)) {\n  sendTextDocumentDidChange(doc);\n} else {\n  sendNotebookDidChange(doc);\n}","typeGuard":"fn is_notebook_document(controller: &DocumentController) -> bool { matches!(controller.as_notebook(), Some(_)) }","tryCatchPattern":"if let Err(e) = session.update_notebook_document(&key, cells, meta, ver, enc) { if e.to_string().contains(\"not point to a notebook document\") { /* fall back to textDocument path */ } }","preventionTips":["Send notebookDocument/didChange only for documents opened as notebooks","Close and reopen with the correct lifecycle if a URI was opened with the wrong kind","Avoid multiple editor plugins opening the same URI with conflicting document kinds"],"tags":["lsp","notebook","documents"],"backgroundTag":"wrong-document-type","analyzedSha":"26f38c119cac42e4d320ba08f09224fdec74af2c","analyzedAt":"2026-09-05T10:32:37.492Z","contentChangedAt":"2026-09-05T10:32:37.492Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}