{"record":{"id":"470ddb7c7b83bff2","repo":"charmbracelet/crush","slug":"invalid-edit-type-w","errorCode":null,"errorMessage":"invalid edit type: %w","messagePattern":"invalid edit type: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/lsp/util/edit.go","lineNumber":241,"sourceCode":"\t\tif change.RenameFile.Options != nil {\n\t\t\tif !change.RenameFile.Options.Overwrite {\n\t\t\t\tif _, err := os.Stat(newPath); err == nil {\n\t\t\t\t\treturn fmt.Errorf(\"target file already exists and overwrite is not allowed: %s\", newPath)\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tif err := os.Rename(oldPath, newPath); err != nil {\n\t\t\treturn fmt.Errorf(\"failed to rename file: %w\", err)\n\t\t}\n\t}\n\n\tif change.TextDocumentEdit != nil {\n\t\ttextEdits := make([]protocol.TextEdit, len(change.TextDocumentEdit.Edits))\n\t\tfor i, edit := range change.TextDocumentEdit.Edits {\n\t\t\tvar err error\n\t\t\ttextEdits[i], err = edit.AsTextEdit()\n\t\t\tif err != nil {\n\t\t\t\treturn fmt.Errorf(\"invalid edit type: %w\", err)\n\t\t\t}\n\t\t}\n\t\treturn applyTextEdits(change.TextDocumentEdit.TextDocument.URI, textEdits, encoding)\n\t}\n\n\treturn nil\n}\n\n// utf32ToByteOffset converts a UTF-32 codepoint offset to a byte offset.\nfunc utf32ToByteOffset(lineText string, codepointOffset uint32) int {\n\tif codepointOffset == 0 {\n\t\treturn 0\n\t}\n\n\tvar codepointCount uint32\n\tfor byteOffset := range lineText {\n\t\tif codepointCount >= codepointOffset {\n\t\t\treturn byteOffset","sourceCodeStart":223,"sourceCodeEnd":259,"githubUrl":"https://github.com/charmbracelet/crush/blob/7944b8e52225d8805e31eacbf7ef24856b0dfb7a/internal/lsp/util/edit.go#L223-L259","documentation":"applyDocumentChange converts each TextDocumentEdit entry via edit.AsTextEdit(). If an edit cannot be represented as a protocol.TextEdit (wrong concrete type / malformed kind), the error from AsTextEdit is wrapped as \"invalid edit type\". It indicates the WorkspaceEdit payload contains an edit shape the client cannot handle.","triggerScenarios":"A TextDocumentEdit.Edits element is a protocol.AnnotatedTextEdit or another variant whose AsTextEdit fails, typically because Kind/annotation data is malformed or the element is nil of an unexpected type.","commonSituations":"Newer LSP servers emitting AnnotatedTextEdit entries; protocol/version mismatches between server and client; buggy server emitting non-conformant edit JSON.","solutions":["Update the LSP protocol/fantasy library so AsTextEdit supports the edit variants your server emits","Inspect edit.Kind/annotations in the failing element and handle/strip it before calling ApplyWorkspaceEdit","Report or work around a server emitting non-conformant edits; disable that feature if necessary"],"exampleFix":"// before\ntextEdits[i], err = edit.AsTextEdit()\n// after\ntextEdits[i], err = edit.AsTextEdit()\nif err != nil {\n    if ann, ok := edit.(protocol.AnnotatedTextEdit); ok {\n        textEdits[i] = ann.TextEdit // strip annotation\n        continue\n    }\n    return fmt.Errorf(\"invalid edit type: %w\", err)\n}","handlingStrategy":"type-guard","validationCode":"for _, e := range docEdit.Edits {\n    if _, err := e.AsTextEdit(); err != nil {\n        return fmt.Errorf(\"unsupported edit in %s: %w\", docEdit.TextDocument.URI, err)\n    }\n}","typeGuard":"func isPlainTextEdit(e protocol.TextEditOrAnnotated) bool {\n    _, err := e.AsTextEdit()\n    return err == nil\n}","tryCatchPattern":"if err := ApplyWorkspaceEdit(edit, enc); err != nil && strings.Contains(err.Error(), \"invalid edit type\") {\n    // filter out unsupported edits and retry with the remainder\n}","preventionTips":["Keep the LSP protocol library (fantasy/powernap) up to date to support annotated edits","Prefer servers known to emit plain TextEdits, or strip annotations client-side","Log and inspect rejected edit elements when integrating a new server"],"tags":["lsp","workspace-edit","protocol","type-mismatch"],"backgroundTag":"invalid-edit-type","analyzedSha":"7944b8e52225d8805e31eacbf7ef24856b0dfb7a","analyzedAt":"2026-08-29T12:48:59.079Z","schemaVersion":2},"datasetVersion":"2026-08-29T17:17:51.833Z"}