{"record":{"id":"1b4c7ad897743f00","repo":"wavetermdev/waveterm","slug":"failed-to-write-file-w-1b4c7a","errorCode":null,"errorMessage":"failed to write file: %w","messagePattern":"failed to write file: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/util/fileutil/fileutil.go","lineNumber":363,"sourceCode":"\t\treturn fmt.Errorf(\"not a regular file: %s\", filePath)\n\t}\n\n\tif fileInfo.Size() > MaxEditFileSize {\n\t\treturn fmt.Errorf(\"file too large for editing: %d bytes (max: %d)\", fileInfo.Size(), MaxEditFileSize)\n\t}\n\n\tcontents, err := os.ReadFile(filePath)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"failed to read file: %w\", err)\n\t}\n\n\tmodifiedContents, err := ApplyEdits(contents, edits)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tif err := os.WriteFile(filePath, modifiedContents, fileInfo.Mode()); err != nil {\n\t\treturn fmt.Errorf(\"failed to write file: %w\", err)\n\t}\n\n\treturn nil\n}\n\n// ReplaceInFilePartial applies edits incrementally up to the first failure.\n// Returns the results for each edit and writes the partially modified content.\nfunc ReplaceInFilePartial(filePath string, edits []EditSpec) ([]EditResult, error) {\n\tfileInfo, err := os.Stat(filePath)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"failed to stat file: %w\", err)\n\t}\n\n\tif !fileInfo.Mode().IsRegular() {\n\t\treturn nil, fmt.Errorf(\"not a regular file: %s\", filePath)\n\t}\n\n\tif fileInfo.Size() > MaxEditFileSize {","sourceCodeStart":345,"sourceCodeEnd":381,"githubUrl":"https://github.com/wavetermdev/waveterm/blob/a4447c1563b2df285ab89e76c82f91e1a1a49c1e/pkg/util/fileutil/fileutil.go#L345-L381","documentation":"After edits apply successfully in memory, ReplaceInFile writes the result back with os.WriteFile using the file's original mode. A failed write (permissions, read-only fs, disk full) is wrapped with this message; note this path uses a plain in-place write, not the atomic temp-file rename.","triggerScenarios":"os.WriteFile(filePath, modifiedContents, fileInfo.Mode()) failing: read-only file mode, directory lacking write permission, disk full, or immutable file attribute.","commonSituations":"Editing a checked-in file made read-only (chmod 444, or read-only from version-control state); full disk; editing files on a read-only mount; Windows file locked by another process.","solutions":["Make the file writable (chmod u+w) or run as a user with write access.","Check disk space and read-only mount status.","Close programs holding a write lock on the file, then retry.","Prefer a write-then-rename flow (e.g. write to a temp file and AtomicWriteFile) if partial writes are a concern."],"exampleFix":"// before\nfileutil.ReplaceInFile(\"settings.json\", edits) // mode 0444\n\n// after\nos.Chmod(path, 0644) // ensure writable\nfileutil.ReplaceInFile(path, edits)","handlingStrategy":"validation","validationCode":"// ensure the file is writable with its current mode\nfi, err := os.Stat(path)\nif err != nil {\n    return err\n}\nif fi.Mode().Perm()&0200 == 0 {\n    return fmt.Errorf(\"%s is read-only (mode %v)\", path, fi.Mode())\n}","typeGuard":null,"tryCatchPattern":"// Go: fix writability, then retry once\nif err := fileutil.ReplaceInFile(path, edits); err != nil {\n    if strings.Contains(err.Error(), \"failed to write file\") {\n        if cerr := os.Chmod(path, 0644); cerr == nil {\n            return fileutil.ReplaceInFile(path, edits)\n        }\n    }\n    return err\n}","preventionTips":["Check the write bit on the file mode before editing","Ensure the process user owns or can write the file","Keep an eye on free disk space","Prefer atomic write-and-rename flows to avoid partial writes"],"tags":["go","filesystem","write"],"backgroundTag":"file-write-failed","analyzedSha":"a4447c1563b2df285ab89e76c82f91e1a1a49c1e","analyzedAt":"2026-09-01T15:26:23.972Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}