{"record":{"id":"97981d78a61b1f9a","repo":"astral-sh/ruff","slug":"internalerror-97981d","errorCode":"InternalError","errorMessage":"failed to deserialize diagnostic data: {err}","messagePattern":"failed to deserialize diagnostic data: (.+?)","errorType":"error_code","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/ruff_server/src/lint.rs","lineNumber":305,"sourceCode":"        document: CheckedDocument::Toml(document),\n    }\n}\n\n/// Converts LSP diagnostics to a list of `DiagnosticFix`es by deserializing associated data on each diagnostic.\npub(crate) fn fixes_for_diagnostics(\n    diagnostics: Vec<lsp_types::Diagnostic>,\n) -> crate::Result<Vec<DiagnosticFix>> {\n    diagnostics\n        .into_iter()\n        .filter(|diagnostic| diagnostic.source.as_deref() == Some(DIAGNOSTIC_NAME))\n        .map(move |mut diagnostic| {\n            let Some(data) = diagnostic.data.take() else {\n                return Ok(None);\n            };\n            let fixed_diagnostic = diagnostic;\n            let associated_data: crate::lint::AssociatedDiagnosticData =\n                serde_json::from_value(data).map_err(|err| {\n                    anyhow::anyhow!(\"failed to deserialize diagnostic data: {err}\")\n                })?;\n            Ok(Some(DiagnosticFix {\n                fixed_diagnostic,\n                code: associated_data.code,\n                title: associated_data.title,\n                noqa_edit: associated_data.noqa_edit,\n                edits: associated_data.edits,\n                is_preferred: associated_data.is_preferred,\n            }))\n        })\n        .filter_map(crate::Result::transpose)\n        .collect()\n}\n\nenum CheckedDocument<'a> {\n    Python {\n        source: SourceKind,\n        index: LineIndex,","sourceCodeStart":287,"sourceCodeEnd":323,"githubUrl":"https://github.com/astral-sh/ruff/blob/d1087a4b9e03d253a88703f34e0869ee4b805456/crates/ruff_server/src/lint.rs#L287-L323","documentation":"When resolving fixes, the server takes diagnostics it previously published (those with source 'ruff' and a `data` payload) and deserializes `data` into an internal AssociatedDiagnosticData structure containing the fix edits, title, and noqa edit. If the diagnostic sent back by the client carries a `data` field that is not that JSON shape, serde fails with this InternalError.","triggerScenarios":"Another extension or the client mutating/stripping the diagnostic `data` before it is echoed back; sending diagnostics produced by a different tool that happen to use source 'ruff'; stale diagnostics published by an older server version still cached client-side after an upgrade (schema drift between versions).","commonSituations":"Editor extensions that rewrite diagnostics for display and lose the opaque data payload; upgrading the Ruff server without clearing diagnostic caches; multiple linters interleaving diagnostics in one editor.","solutions":["Restart the language server or re-run linting so fresh diagnostics with the current schema are published and cached","Ensure the client passes diagnostics back byte-for-byte, especially the opaque `data` field","Keep the extension and server versions in sync; clear cached diagnostics after upgrades","Filter to diagnostics with source === 'ruff' before invoking fix resolution"],"exampleFix":"// before: resolving a diagnostic whose data was rewritten by middleware\nawait conn.sendRequest('codeAction/resolve', { ...action }); // data mangled -> deserialization error\n\n// after: keep ruff diagnostics untouched\nconst ruffDiagnostics = allDiagnostics.filter(d => d.source === 'ruff' && d.data !== undefined);\n// pass these, unmodified, into fix resolution","handlingStrategy":"validation","validationCode":"// Only feed ruff-origin diagnostics with intact data payloads into fix resolution\nconst resolvable = diagnostics.filter(\n  (d) => d.source === 'ruff' && d.data !== null && d.data !== undefined,\n);\nif (!resolvable.some(d => d === action.diagnostics?.[0])) {\n  throw new Error('action carries a non-ruff or degraded diagnostic');\n}","typeGuard":"function hasRuffData(d: lsp.Diagnostic): boolean {\n  return d.source === 'ruff' && d.data !== undefined && typeof d.data === 'object';\n}","tryCatchPattern":null,"preventionTips":["Treat diagnostic.data as opaque and pass it back byte-identical","Clear cached ruff diagnostics whenever the server version changes or restarts","Avoid letting other extensions rewrite diagnostics that will be echoed to the server"],"tags":["lsp","diagnostics","deserialization","fix-all","ruff-server"],"backgroundTag":"diagnostic-data-deserialization-failed","analyzedSha":"d1087a4b9e03d253a88703f34e0869ee4b805456","analyzedAt":"2026-08-20T16:33:49.445Z","contentChangedAt":"2026-08-20T16:33:49.445Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}