{"record":{"id":"dd9387f17efdedbb","repo":"charmbracelet/crush","slug":"failed-to-apply-edit-w","errorCode":null,"errorMessage":"failed to apply edit: %w","messagePattern":"failed to apply edit: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/lsp/util/edit.go","lineNumber":63,"sourceCode":"\t\t\t}\n\t\t}\n\t}\n\n\t// Sort edits in reverse order\n\tsortedEdits := make([]protocol.TextEdit, len(edits))\n\tcopy(sortedEdits, edits)\n\tsort.Slice(sortedEdits, func(i, j int) bool {\n\t\tif sortedEdits[i].Range.Start.Line != sortedEdits[j].Range.Start.Line {\n\t\t\treturn sortedEdits[i].Range.Start.Line > sortedEdits[j].Range.Start.Line\n\t\t}\n\t\treturn sortedEdits[i].Range.Start.Character > sortedEdits[j].Range.Start.Character\n\t})\n\n\t// Apply each edit\n\tfor _, edit := range sortedEdits {\n\t\tnewLines, err := applyTextEdit(lines, edit, encoding)\n\t\tif err != nil {\n\t\t\treturn fmt.Errorf(\"failed to apply edit: %w\", err)\n\t\t}\n\t\tlines = newLines\n\t}\n\n\t// Join lines with proper line endings\n\tvar newContent strings.Builder\n\tfor i, line := range lines {\n\t\tif i > 0 {\n\t\t\tnewContent.WriteString(lineEnding)\n\t\t}\n\t\tnewContent.WriteString(line)\n\t}\n\n\t// Only add a newline if the original file had one and we haven't already added it\n\tif endsWithNewline && !strings.HasSuffix(newContent.String(), lineEnding) {\n\t\tnewContent.WriteString(lineEnding)\n\t}\n","sourceCodeStart":45,"sourceCodeEnd":81,"githubUrl":"https://github.com/charmbracelet/crush/blob/7944b8e52225d8805e31eacbf7ef24856b0dfb7a/internal/lsp/util/edit.go#L45-L81","documentation":"applyTextEdits applies each sorted edit via applyTextEdit; if any individual edit fails (invalid positions, encoding errors), the whole file application aborts and the underlying error is wrapped with this message. The file is left unmodified on disk for that failing edit, but earlier edits in the loop have already mutated the in-memory lines.","triggerScenarios":"An edit whose Range.End line/character is invalid for the document (stale positions, wrong offset encoding) causing applyTextEdit to return an error during ApplyWorkspaceEdit.","commonSituations":"Stale edit positions computed against an older document version that changed since the edit was produced; client and server disagreeing on position encoding (UTF-8 vs UTF-16).","solutions":["Regenerate the edits against the current document version.","Ensure the OffsetEncoding passed matches the encoding used to compute positions.","Inspect the wrapped cause (%w) to see which edit/position was invalid.","Validate each edit's range against the document length before applying."],"exampleFix":"// before\nedit.Range.End.Line = 999 // stale position\nutil.ApplyWorkspaceEdit(ctx, we)\n// after\nedit.Range.End.Line = currentDocLineCount() // recompute from fresh snapshot\nutil.ApplyWorkspaceEdit(ctx, we)","handlingStrategy":"try-catch","validationCode":"for _, e := range edits {\n    if e.Range.End.Line >= uint32(docLineCount) {\n        return fmt.Errorf(\"edit end line %d out of bounds\", e.Range.End.Line)\n    }\n}","typeGuard":null,"tryCatchPattern":"if err := util.ApplyWorkspaceEdit(ctx, we); err != nil {\n    var wrapped interface{ Unwrap() error }\n    if errors.As(err, &wrapped) {\n        log.Printf(\"edit application failed: %v\", errors.Unwrap(err))\n    }\n}","preventionTips":["Regenerate edits from the latest document version.","Keep the position encoding consistent between producer and consumer.","Apply edits promptly before the document changes underneath."],"tags":["lsp","workspace-edit","position-encoding"],"backgroundTag":"invalid-text-edit-range","analyzedSha":"7944b8e52225d8805e31eacbf7ef24856b0dfb7a","analyzedAt":"2026-08-29T12:48:59.079Z","schemaVersion":2},"datasetVersion":"2026-08-29T17:17:51.833Z"}