{"record":{"id":"028f7e688ea6cf30","repo":"slint-ui/slint","slug":"just-added-if-missing","errorCode":null,"errorMessage":"just added if missing","messagePattern":"just added if missing","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/editor-preview/editing/text_edit.rs","lineNumber":269,"sourceCode":") -> crate::Result<Vec<EditedText>> {\n    let mut processing = HashMap::new();\n\n    for (doc, edit) in EditIterator::new(workspace_edit) {\n        // This is ugly but necessary since the constructor might error out:-/\n        if !processing.contains_key(&doc.uri) {\n            let Some(document) = document_cache.get_document(&doc.uri) else {\n                continue;\n            };\n            let Some(document_node) = &document.node else {\n                continue;\n            };\n            let editor = TextEditor::new(document_node.source_file.clone())?;\n            processing.insert(doc.uri.clone(), editor);\n        }\n\n        processing\n            .get_mut(&doc.uri)\n            .expect(\"just added if missing\")\n            .apply(edit, document_cache.format)?;\n    }\n\n    Ok(processing\n        .drain()\n        .filter_map(|(url, v)| {\n            let edit_result = v.finalize()?;\n            Some(EditedText { url, contents: edit_result.0 })\n        })\n        .collect())\n}\n\n/// Given a WorkspaceEdit, return a reversed version of it (that undoes it)\n/// Returns none if it cannot be reverted (eg, if it deletes files)\npub fn reversed_edit(\n    document_cache: &crate::DocumentCache,\n    edit: &lsp_types::WorkspaceEdit,\n) -> Option<lsp_types::WorkspaceEdit> {","sourceCodeStart":251,"sourceCodeEnd":287,"githubUrl":"https://github.com/slint-ui/slint/blob/bb937076de3f7919766c1f25e2e969367cf77e9a/internal/editor-preview/editing/text_edit.rs#L251-L287","documentation":"This panic comes from an `.expect()` on a HashMap `get_mut` inside `apply_workspace_edit` in the LSP text-editing pipeline. The editor for a document URI is inserted into the `processing` map immediately before lookup, so a miss is an impossible-by-construction state: the URI key was mutated between insert and fetch, or the insertion branch was skipped (e.g. `TextEditor::new` path changed) while the fetch still runs. It is an internal invariant violation, not something a caller can influence through the LSP protocol.","triggerScenarios":"Applying a `workspace/applyEdit` (or document edit) request when the `processing` map entry for `doc.uri` was not inserted on the preceding iteration because the code path that creates `TextEditor::new(document_node.source_file.clone())` did not run for that URI, yet the code still reaches the unconditional `get_mut(&doc.uri)`.","commonSituations":"Occur only after a refactor of the insert/lookup loop in `apply_workspace_edit`; hit by LSP users when the server processes edits for a document whose source-file node mapping changed (e.g. after a document close/reopen race or stale document cache).","solutions":["Re-run the LSP operation; a single hiccup in document tracking usually clears on the next edit request","Update the Slint LSP to the latest version — this panic indicates an internal bug likely fixed upstream","File a bug with the workspace edit request that triggered it (contents of the edit and document URI)","As a workaround, save and reopen the affected file so the server rebuilds its document cache"],"exampleFix":"// before\nprocessing\n    .get_mut(&doc.uri)\n    .expect(\"just added if missing\")\n    .apply(edit, document_cache.format)?;\n// after\nlet editor = processing\n    .get_mut(&doc.uri)\n    .ok_or_else(|| anyhow::anyhow!(\"no editor registered for {}\", doc.uri))?;\neditor.apply(edit, document_cache.format)?;","handlingStrategy":"validation","validationCode":"assert!(processing.contains_key(&doc.uri), \"editor must be registered before apply\");","typeGuard":null,"tryCatchPattern":"// Rust panics cannot be caught without catch_unwind; fix the invariant instead\nmatch processing.get_mut(&doc.uri) {\n    Some(editor) => editor.apply(edit, document_cache.format)?,\n    None => return Err(anyhow::anyhow!(\"missing editor for {}\", doc.uri)),\n}","preventionTips":["Always insert into the map in the same iteration as the lookup (use the entry() API)","Never assume insert-then-get invariants survive refactors — use `.entry(uri)` to fuse them","Cover the edit-apply loop with a test that exercises a missing-document edge case"],"tags":["lsp","internal-invariant","rust","panic"],"backgroundTag":"internal-invariant-violation","analyzedSha":"bb937076de3f7919766c1f25e2e969367cf77e9a","analyzedAt":"2026-09-16T01:37:20.251Z","contentChangedAt":"2026-09-16T01:37:20.251Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}