charmbracelet/crush · error
failed to read file: %w
Error message
failed to read file: %w
What it means
applyTextEdits reads the target file from disk before applying LSP text edits. When os.ReadFile fails (missing file, permission denied, path is a directory), the OS error is wrapped with this message. It indicates the workspace edit referenced a document whose on-disk state is unreadable.
Source
Thrown at internal/lsp/util/edit.go:23
"fmt"
"os"
"sort"
"strings"
powernap "github.com/charmbracelet/x/powernap/pkg/lsp"
"github.com/charmbracelet/x/powernap/pkg/lsp/protocol"
)
func applyTextEdits(uri protocol.DocumentURI, edits []protocol.TextEdit, encoding powernap.OffsetEncoding) error {
path, err := uri.Path()
if err != nil {
return fmt.Errorf("invalid URI: %w", err)
}
// Read the file content
content, err := os.ReadFile(path)
if err != nil {
return fmt.Errorf("failed to read file: %w", err)
}
// Detect line ending style
var lineEnding string
if bytes.Contains(content, []byte("\r\n")) {
lineEnding = "\r\n"
} else {
lineEnding = "\n"
}
// Track if file ends with a newline
endsWithNewline := len(content) > 0 && bytes.HasSuffix(content, []byte(lineEnding))
// Split into lines without the endings
lines := strings.Split(string(content), lineEnding)
// Check for overlapping edits
for i, edit1 := range edits {View on GitHub (pinned to 7944b8e522)
Solutions
- Verify the file exists at the path encoded in the URI before applying the edit (os.Stat).
- Check file read permissions for the user running the process.
- Regenerate the workspace edit from a fresh document snapshot so URIs are current.
- If the file should be newly created, send a CreateFile change instead of a TextDocumentEdit.
Example fix
// before
// blind apply
err := util.ApplyWorkspaceEdit(ctx, edit)
// after
if _, statErr := os.Stat(path); statErr != nil {
return fmt.Errorf("file missing before edit: %w", statErr)
}
err := util.ApplyWorkspaceEdit(ctx, edit) Defensive patterns
Strategy: validation
Validate before calling
if info, err := os.Stat(path); err != nil || info.IsDir() {
return fmt.Errorf("cannot apply edit: %s is not a readable file", path)
} Try / catch
var readErr *fs.PathError
if errors.As(err, &readErr) && errors.Is(readErr, fs.ErrNotExist) {
// recreate or refresh document before retrying
} Prevention
- Stat the file before constructing TextDocumentEdits.
- Refresh document URIs after any external git/file operation.
- Run the LSP client with sufficient filesystem permissions.
When it happens
Trigger: Calling ApplyWorkspaceEdit/applyDocumentChange with a TextDocumentEdit whose URI resolves to a path that does not exist, lacks read permission, or points to a directory instead of a regular file.
Common situations: File was deleted or moved by an external tool between edit generation and application; stale URI after a git operation; running the process as a user without read access to the file.
Related errors
- error reading file: %w
- invalid URI: %w
- overlapping edits detected between edit %d and %d
- failed to apply edit: %w
- failed to write file: %w
AI-assisted analysis of charmbracelet/crush@7944b8e522 (2026-08-29).
Data as JSON: /api/errors/e2a97ec5c6c9d1db.
Report an issue: GitHub.