{"record":{"id":"04678c588d4d24fb","repo":"astral-sh/ruff","slug":"tried-to-open-unavailable-document-key","errorCode":null,"errorMessage":"Tried to open unavailable document `{key}`","messagePattern":"Tried to open unavailable document `(.+?)`","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/ruff_server/src/session/index.rs","lineNumber":156,"sourceCode":"        }\n    }\n\n    pub(super) fn update_notebook_document(\n        &mut self,\n        key: &DocumentKey,\n        cells: Option<lsp_types::NotebookDocumentCellChanges>,\n        metadata: Option<serde_json::Map<String, serde_json::Value>>,\n        new_version: DocumentVersion,\n        encoding: PositionEncoding,\n    ) -> crate::Result<()> {\n        // update notebook cell index\n        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","sourceCodeStart":138,"sourceCodeEnd":174,"githubUrl":"https://github.com/astral-sh/ruff/blob/26f38c119cac42e4d320ba08f09224fdec74af2c/crates/ruff_server/src/session/index.rs#L138-L174","documentation":"When a `notebookDocument/didChange` includes a cell-structure change with `did_open` cells, the server first resolves the notebook's URI from the document key. If no URI is indexed for that key, it bails because it cannot register the newly opened cells under the notebook's path. This prevents orphaned cell mappings in `self.notebook_cells`.","triggerScenarios":"Calling `session.update_notebook_document` with a `NotebookDocumentCellChangeStructure` whose `did_open` is Some, while `uri_for_key(key)` returns None — i.e. the notebook was never opened or was already closed.","commonSituations":"Client sends didChange with open-cell structure events for a notebook that was closed via `notebookDocument/didClose`; out-of-order LSP notifications after a server restart; notebook opened in one workspace but edited via a key from another.","solutions":["Ensure `notebookDocument/didOpen` was sent before sending didChange with did_open cell events","Reopen the notebook (didOpen) if it was closed, then resend the change","Restart the Ruff server if its session state has desynchronized from the client"],"exampleFix":null,"handlingStrategy":"validation","validationCode":"// client-side: only send did_open structure changes for notebooks already opened via didOpen\nif (!openedNotebooks.has(notebookUri)) {\n  await sendNotebookDidOpen(notebook); // open first\n}\nsendNotebookDidChangeWithCellOpens(notebook);","typeGuard":null,"tryCatchPattern":"if let Err(e) = session.update_notebook_document(&key, cells, meta, ver, enc) { if e.to_string().contains(\"Tried to open unavailable document\") { /* reopen notebook then retry once */ } }","preventionTips":["Always open notebooks with notebookDocument/didOpen before sending didChange with did_open events","Do not send cell-structure opens for notebooks that were closed","Resynchronize by restarting the server after desynchronization is detected"],"tags":["lsp","notebook","documents"],"backgroundTag":"document-not-open","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"}