{"record":{"id":"8f9fdf53f04a227e","repo":"alibaba/open-code-review","slug":"create-output-file-s-w","errorCode":null,"errorMessage":"create output file %s: %w","messagePattern":"create output file (.+?): %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"cmd/opencodereview/shared.go","lineNumber":506,"sourceCode":"// \"Results written\" hint is printed to stderr only after the first successful\n// Write, so agents never see a path hint for a file that stayed empty or was\n// never persisted.\ntype lazyFileWriter struct {\n\tpath     string\n\tstrip    bool // strip ANSI when the target format is text\n\tonce     sync.Once\n\tfile     *os.File\n\tstripper *stripAnsiWriter\n\terr      error // os.Create error\n\twriteErr error // first error from a Write\n\thinted   bool  // hint already printed after a successful Write\n}\n\nfunc (w *lazyFileWriter) Write(p []byte) (int, error) {\n\tw.once.Do(func() {\n\t\tf, err := os.Create(w.path)\n\t\tif err != nil {\n\t\t\tw.err = fmt.Errorf(\"create output file %s: %w\", w.path, err)\n\t\t\treturn\n\t\t}\n\t\tw.file = f\n\t\tif w.strip {\n\t\t\tw.stripper = &stripAnsiWriter{dst: f}\n\t\t}\n\t})\n\tif w.err != nil {\n\t\treturn 0, w.err\n\t}\n\tvar n int\n\tvar err error\n\tif w.stripper != nil {\n\t\tn, err = w.stripper.Write(p)\n\t} else {\n\t\tn, err = w.file.Write(p)\n\t}\n\tif err != nil && w.writeErr == nil {","sourceCodeStart":488,"sourceCodeEnd":524,"githubUrl":"https://github.com/alibaba/open-code-review/blob/5cf97d0d15cbd41b602513c4be3bfec3cee5bf7f/cmd/opencodereview/shared.go#L488-L524","documentation":"lazyFileWriter defers opening its output file until the first Write; if os.Create fails it records `create output file %s: %w` and the command fails non-zero. os.Create fails when the parent directory is missing or unwritable, the path is a directory, or the target exists without write permission. It wraps the syscall error, so ENOENT/EACCES/EISDIR identify the exact cause.","triggerScenarios":"ocr invoked with --output pointing into a nonexistent directory, to a read-only location, or to an existing file the user cannot overwrite — triggered only when the first output byte is written.","commonSituations":"Typo in the output path's parent directory; CI running as a non-root user writing to a root-owned path; output on a read-only or full filesystem; pointing at an existing directory-named file.","solutions":["Ensure the parent directory exists (mkdir -p) and is writable by the running user","Check existing file permissions (ls -l) and remove/chmod the blocking file","Verify the filesystem is not read-only or full (df, mount)","Use --output - to write to stdout if file output is not required"],"exampleFix":"// before\nocr review --output /var/reports/out.md   # /var/reports missing\n// after\nmkdir -p /var/reports && ocr review --output /var/reports/out.md","handlingStrategy":"validation","validationCode":"if out := flagOutput; out != \"\" && out != \"-\" {\n\tparent := filepath.Dir(out)\n\tif st, err := os.Stat(parent); err != nil || !st.IsDir() {\n\t\tos.MkdirAll(parent, 0o755)\n\t}\n\tif st, err := os.Stat(out); err == nil && !st.Mode().Perm().Write() {\n\t\treturn fmt.Errorf(\"cannot write %s: permission denied\", out)\n\t}\n}","typeGuard":null,"tryCatchPattern":"if err := closer(); err != nil {\n\tvar pe *fs.PathError\n\tif errors.As(err, &pe) && errors.Is(pe.Err, syscall.EACCES) {\n\t\t// fall back to stdout or a temp file\n\t}\n\treturn err\n}","preventionTips":["mkdir -p the output parent directory in scripts before running","Write outputs to a per-user writable directory in CI","Check disk space (df) on the output filesystem"],"tags":["go","filesystem","io"],"backgroundTag":"output-file-write-failed","analyzedSha":"5cf97d0d15cbd41b602513c4be3bfec3cee5bf7f","analyzedAt":"2026-09-02T02:08:09.116Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}