{"record":{"id":"22c3a49148cf484e","repo":"astral-sh/ruff","slug":"notebook-document-expected-from-notebook-source-ki","errorCode":null,"errorMessage":"Notebook document expected from notebook source kind","messagePattern":"Notebook document expected from notebook source kind","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/ruff_server/src/fix.rs","lineNumber":107,"sourceCode":"    }\n\n    // fast path: if `transformed` is still borrowed, no changes were made and we can return early\n    if let Cow::Borrowed(_) = transformed {\n        return Ok(Fixes::default());\n    }\n\n    if let (Some(source_notebook), Some(modified_notebook)) =\n        (source_kind.as_ipy_notebook(), transformed.as_ipy_notebook())\n    {\n        fn cell_source(cell: &ruff_notebook::Cell) -> String {\n            match cell.source() {\n                SourceValue::String(string) => string.clone(),\n                SourceValue::StringArray(array) => array.join(\"\"),\n            }\n        }\n\n        let Some(notebook) = query.as_notebook() else {\n            anyhow::bail!(\"Notebook document expected from notebook source kind\");\n        };\n        let mut fixes = Fixes::default();\n        for ((source, modified), uri) in source_notebook\n            .cells()\n            .iter()\n            .map(cell_source)\n            .zip(modified_notebook.cells().iter().map(cell_source))\n            .zip(notebook.uris())\n        {\n            let source_index = LineIndex::from_source_text(&source);\n            let modified_index = LineIndex::from_source_text(&modified);\n\n            let Replacement {\n                source_range,\n                modified_range,\n            } = Replacement::between(\n                &source,\n                source_index.line_starts(),","sourceCodeStart":89,"sourceCodeEnd":125,"githubUrl":"https://github.com/astral-sh/ruff/blob/26f38c119cac42e4d320ba08f09224fdec74af2c/crates/ruff_server/src/fix.rs#L89-L125","documentation":"In the Ruff language server's `fix_all`, when the request targets a notebook source kind, the code calls `query.as_notebook()` and bails with this anyhow error if the query does not actually carry a notebook document. This is an internal invariant violation: the source kind says notebook but the document payload is not one.","triggerScenarios":"Sending a code-action/fix-all request whose document identifier claims a notebook source kind while the resolved query holds a plain string document (or vice versa the notebook lookup fails after conversion).","commonSituations":"Editor/plugin bugs constructing fix-all params for notebook cells with stale or wrong URIs; race where a notebook was closed/converted to a text document between request and handling; custom clients mislabeling source kinds.","solutions":["Reopen or refocus the notebook in the editor so the server re-resolves the document, then retry the fix-all request","Check the client request payload: the document URI/kind must match an open notebook document","Update the Ruff language server / editor extension; if reproducible, file a bug with reproduction steps since this indicates an internal mismatch"],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"client.onRequest('textDocument/codeAction', async (params) => {\n  try {\n    return await requestFixAll(params);\n  } catch (e) {\n    if (String(e.message).includes('Notebook document expected')) {\n      // re-resolve the document and retry once\n      await reopenNotebook(params.textDocument.uri);\n      return await requestFixAll(params);\n    }\n    throw e;\n  }\n});","preventionTips":["Keep notebook URIs synchronized between client and server","Avoid sending fix-all requests for cells of closed notebooks","Update the Ruff VS Code/editor extension to match the server version","If reproducible, file an upstream bug with steps"],"tags":["ruff","lsp","notebook","internal-invariant"],"backgroundTag":"unexpected-document-type","analyzedSha":"26f38c119cac42e4d320ba08f09224fdec74af2c","analyzedAt":"2026-09-05T10:32:37.492Z","contentChangedAt":"2026-09-05T10:32:37.492Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}