charmbracelet/crush · error

failed to apply edit: %w

Error message

failed to apply edit: %w

What it means

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.

Source

Thrown at internal/lsp/util/edit.go:63

			}
		}
	}

	// Sort edits in reverse order
	sortedEdits := make([]protocol.TextEdit, len(edits))
	copy(sortedEdits, edits)
	sort.Slice(sortedEdits, func(i, j int) bool {
		if sortedEdits[i].Range.Start.Line != sortedEdits[j].Range.Start.Line {
			return sortedEdits[i].Range.Start.Line > sortedEdits[j].Range.Start.Line
		}
		return sortedEdits[i].Range.Start.Character > sortedEdits[j].Range.Start.Character
	})

	// Apply each edit
	for _, edit := range sortedEdits {
		newLines, err := applyTextEdit(lines, edit, encoding)
		if err != nil {
			return fmt.Errorf("failed to apply edit: %w", err)
		}
		lines = newLines
	}

	// Join lines with proper line endings
	var newContent strings.Builder
	for i, line := range lines {
		if i > 0 {
			newContent.WriteString(lineEnding)
		}
		newContent.WriteString(line)
	}

	// Only add a newline if the original file had one and we haven't already added it
	if endsWithNewline && !strings.HasSuffix(newContent.String(), lineEnding) {
		newContent.WriteString(lineEnding)
	}

View on GitHub (pinned to 7944b8e522)

Solutions

  1. Regenerate the edits against the current document version.
  2. Ensure the OffsetEncoding passed matches the encoding used to compute positions.
  3. Inspect the wrapped cause (%w) to see which edit/position was invalid.
  4. Validate each edit's range against the document length before applying.

Example fix

// before
edit.Range.End.Line = 999 // stale position
util.ApplyWorkspaceEdit(ctx, we)
// after
edit.Range.End.Line = currentDocLineCount() // recompute from fresh snapshot
util.ApplyWorkspaceEdit(ctx, we)
Defensive patterns

Strategy: try-catch

Validate before calling

for _, e := range edits {
    if e.Range.End.Line >= uint32(docLineCount) {
        return fmt.Errorf("edit end line %d out of bounds", e.Range.End.Line)
    }
}

Try / catch

if err := util.ApplyWorkspaceEdit(ctx, we); err != nil {
    var wrapped interface{ Unwrap() error }
    if errors.As(err, &wrapped) {
        log.Printf("edit application failed: %v", errors.Unwrap(err))
    }
}

Prevention

When it happens

Trigger: 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.

Common situations: 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).

Related errors


AI-assisted analysis of charmbracelet/crush@7944b8e522 (2026-08-29). Data as JSON: /api/errors/dd9387f17efdedbb. Report an issue: GitHub.