{"record":{"id":"0b07889371d3d27d","repo":"charmbracelet/crush","slug":"failed-to-write-file-w-0b0788","errorCode":null,"errorMessage":"failed to write file: %w","messagePattern":"failed to write file: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/lsp/util/edit.go","lineNumber":83,"sourceCode":"\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\n\tif err := os.WriteFile(path, []byte(newContent.String()), 0o644); err != nil {\n\t\treturn fmt.Errorf(\"failed to write file: %w\", err)\n\t}\n\n\treturn nil\n}\n\nfunc applyTextEdit(lines []string, edit protocol.TextEdit, encoding powernap.OffsetEncoding) ([]string, error) {\n\tstartLine := int(edit.Range.Start.Line)\n\tendLine := int(edit.Range.End.Line)\n\n\t// Validate positions before accessing lines.\n\tif startLine < 0 || startLine >= len(lines) {\n\t\treturn nil, fmt.Errorf(\"invalid start line: %d\", startLine)\n\t}\n\tif endLine < 0 || endLine >= len(lines) {\n\t\tendLine = len(lines) - 1\n\t}\n\n\tvar startChar, endChar int","sourceCodeStart":65,"sourceCodeEnd":101,"githubUrl":"https://github.com/charmbracelet/crush/blob/7944b8e52225d8805e31eacbf7ef24856b0dfb7a/internal/lsp/util/edit.go#L65-L101","documentation":"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.","triggerScenarios":"os.WriteFile returning ENOENT/EACCES/EROFS/ENOSPC when persisting the edited content during ApplyWorkspaceEdit.","commonSituations":"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.","solutions":["Check write permission on the file and its parent directory.","Confirm the file still exists on disk right before applying edits.","Ensure the process/user has write access to the mount (not read-only).","Retry after resolving external locks or disk-space issues."],"exampleFix":"// before\n// no permission check\nerr := util.ApplyWorkspaceEdit(ctx, we)\n// after\nif info, err := os.Stat(path); err == nil && info.Mode().Perm()&0o200 == 0 {\n    os.Chmod(path, 0o644)\n}\nerr := util.ApplyWorkspaceEdit(ctx, we)","handlingStrategy":"try-catch","validationCode":"if info, err := os.Stat(path); err != nil {\n    return err\n} else if info.Mode().Perm()&0o200 == 0 {\n    return fmt.Errorf(\"%s is not writable\", path)\n}","typeGuard":null,"tryCatchPattern":"var writeErr *fs.PathError\nif errors.As(err, &writeErr) && errors.Is(writeErr.Err, syscall.EACCES) {\n    // fix permissions or run with adequate privileges\n}","preventionTips":["Check file writability before editing.","Avoid editing files on read-only mounts.","Run agents/tools with a user that owns or can write target files."],"tags":["lsp","file-io","permissions"],"backgroundTag":"file-write-failed","analyzedSha":"7944b8e52225d8805e31eacbf7ef24856b0dfb7a","analyzedAt":"2026-08-29T12:48:59.079Z","schemaVersion":2},"datasetVersion":"2026-08-29T17:17:51.833Z"}