charmbracelet/crush · error

failed to write file: %w

Error message

failed to write file: %w

What it means

After edits are applied in memory, applyTextEdits writes the result back with os.WriteFile. This error wraps any write failure (permission denied, read-only filesystem, directory removed, disk full). The in-memory result is discarded because the write failed.

Source

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

		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)
	}

	if err := os.WriteFile(path, []byte(newContent.String()), 0o644); err != nil {
		return fmt.Errorf("failed to write file: %w", err)
	}

	return nil
}

func applyTextEdit(lines []string, edit protocol.TextEdit, encoding powernap.OffsetEncoding) ([]string, error) {
	startLine := int(edit.Range.Start.Line)
	endLine := int(edit.Range.End.Line)

	// Validate positions before accessing lines.
	if startLine < 0 || startLine >= len(lines) {
		return nil, fmt.Errorf("invalid start line: %d", startLine)
	}
	if endLine < 0 || endLine >= len(lines) {
		endLine = len(lines) - 1
	}

	var startChar, endChar int

View on GitHub (pinned to 7944b8e522)

Solutions

  1. Check write permission on the file and its parent directory.
  2. Confirm the file still exists on disk right before applying edits.
  3. Ensure the process/user has write access to the mount (not read-only).
  4. Retry after resolving external locks or disk-space issues.

Example fix

// before
// no permission check
err := util.ApplyWorkspaceEdit(ctx, we)
// after
if info, err := os.Stat(path); err == nil && info.Mode().Perm()&0o200 == 0 {
    os.Chmod(path, 0o644)
}
err := util.ApplyWorkspaceEdit(ctx, we)
Defensive patterns

Strategy: try-catch

Validate before calling

if info, err := os.Stat(path); err != nil {
    return err
} else if info.Mode().Perm()&0o200 == 0 {
    return fmt.Errorf("%s is not writable", path)
}

Try / catch

var writeErr *fs.PathError
if errors.As(err, &writeErr) && errors.Is(writeErr.Err, syscall.EACCES) {
    // fix permissions or run with adequate privileges
}

Prevention

When it happens

Trigger: os.WriteFile returning ENOENT/EACCES/EROFS/ENOSPC when persisting the edited content during ApplyWorkspaceEdit.

Common situations: File deleted by another process after being read; editing files under a read-only mount or container layer; running as a non-privileged user on root-owned files; sandboxed agents without write permissions.

Related errors


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