charmbracelet/crush · error
failed to apply text edits: %w
Error message
failed to apply text edits: %w
What it means
ApplyWorkspaceEdit iterates the WorkspaceEdit.Changes map (uri -> []TextEdit) and applies each set with applyTextEdits. Any failure there (missing document, bad positions, IO error) is wrapped as "failed to apply text edits". The Changes field is the legacy/simpler shape of a WorkspaceEdit as opposed to DocumentChanges.
Source
Thrown at internal/lsp/util/edit.go:273
var codepointCount uint32
for byteOffset := range lineText {
if codepointCount >= codepointOffset {
return byteOffset
}
codepointCount++
}
return len(lineText)
}
// ApplyWorkspaceEdit applies the given WorkspaceEdit to the filesystem.
// The encoding parameter specifies the position encoding used by the LSP server
// (UTF8, UTF16, or UTF32). This affects how character offsets are interpreted.
func ApplyWorkspaceEdit(edit protocol.WorkspaceEdit, encoding powernap.OffsetEncoding) error {
// Handle Changes field
for uri, textEdits := range edit.Changes {
if err := applyTextEdits(uri, textEdits, encoding); err != nil {
return fmt.Errorf("failed to apply text edits: %w", err)
}
}
// Handle DocumentChanges field
for _, change := range edit.DocumentChanges {
if err := applyDocumentChange(change, encoding); err != nil {
return fmt.Errorf("failed to apply document change: %w", err)
}
}
return nil
}
// rangesOverlap checks if two LSP ranges overlap.
// Per the LSP specification, ranges are half-open intervals [start, end),
// so adjacent ranges where one's end equals another's start do NOT overlap.
// See https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#range
func rangesOverlap(r1, r2 protocol.Range) bool {View on GitHub (pinned to 7944b8e522)
Solutions
- Read the wrapped inner error to see whether it is a range/position or IO problem
- Ensure the document is open/registered with the LSP client before applying edits
- Pass the correct OffsetEncoding negotiated with the server
- Reload the file and re-request the edit if it changed since it was produced
Example fix
// before
err := ApplyWorkspaceEdit(edit, powernap.EncodingUTF16)
// after
if err := ApplyWorkspaceEdit(edit, serverNegotiatedEncoding); err != nil {
if strings.Contains(err.Error(), "apply text edits") {
// reload document and retry
}
return err
} Defensive patterns
Strategy: try-catch
Validate before calling
for uri, edits := range edit.Changes {
doc, ok := openDocs[uri]
if !ok {
return fmt.Errorf("document not open: %s", uri)
}
for _, e := range edits {
if e.Range.End.Line > uint32(len(doc.Lines())) {
return fmt.Errorf("range out of bounds for %s", uri)
}
}
} Try / catch
if err := ApplyWorkspaceEdit(edit, enc); err != nil {
var inner error
for e := err; e != nil; e = errors.Unwrap(e) { inner = e }
log.Printf("text edits failed for %s: %v", uriOf(edit), inner)
} Prevention
- Only apply edits to documents your client has opened and holds content for
- Use the OffsetEncoding negotiated during LSP initialization
- Re-fetch edits if the document changed on disk since they were produced
When it happens
Trigger: Server returns WorkspaceEdit.Changes entries and applyTextEdits fails, e.g. the target URI is not open/known so its content cannot be read, or the edit's range exceeds the document bounds.
Common situations: Edits referencing a file the client never opened; encoding mismatch (UTF-8 vs UTF-16 offsets from OffsetEncoding) producing out-of-range positions; file changed on disk since the server computed the edit; diagnostics-quickfix applied to a file that was modified.
Related errors
- invalid URI: %w
- failed to read file: %w
- overlapping edits detected between edit %d and %d
- failed to apply edit: %w
- target file already exists and overwrite is not allowed: %s
AI-assisted analysis of charmbracelet/crush@7944b8e522 (2026-08-29).
Data as JSON: /api/errors/e1448352ea80de4a.
Report an issue: GitHub.