alibaba/open-code-review · error

create output file %s: %w

Error message

create output file %s: %w

What it means

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.

Source

Thrown at cmd/opencodereview/shared.go:506

// "Results written" hint is printed to stderr only after the first successful
// Write, so agents never see a path hint for a file that stayed empty or was
// never persisted.
type lazyFileWriter struct {
	path     string
	strip    bool // strip ANSI when the target format is text
	once     sync.Once
	file     *os.File
	stripper *stripAnsiWriter
	err      error // os.Create error
	writeErr error // first error from a Write
	hinted   bool  // hint already printed after a successful Write
}

func (w *lazyFileWriter) Write(p []byte) (int, error) {
	w.once.Do(func() {
		f, err := os.Create(w.path)
		if err != nil {
			w.err = fmt.Errorf("create output file %s: %w", w.path, err)
			return
		}
		w.file = f
		if w.strip {
			w.stripper = &stripAnsiWriter{dst: f}
		}
	})
	if w.err != nil {
		return 0, w.err
	}
	var n int
	var err error
	if w.stripper != nil {
		n, err = w.stripper.Write(p)
	} else {
		n, err = w.file.Write(p)
	}
	if err != nil && w.writeErr == nil {

View on GitHub (pinned to 5cf97d0d15)

Solutions

  1. Ensure the parent directory exists (mkdir -p) and is writable by the running user
  2. Check existing file permissions (ls -l) and remove/chmod the blocking file
  3. Verify the filesystem is not read-only or full (df, mount)
  4. Use --output - to write to stdout if file output is not required

Example fix

// before
ocr review --output /var/reports/out.md   # /var/reports missing
// after
mkdir -p /var/reports && ocr review --output /var/reports/out.md
Defensive patterns

Strategy: validation

Validate before calling

if out := flagOutput; out != "" && out != "-" {
	parent := filepath.Dir(out)
	if st, err := os.Stat(parent); err != nil || !st.IsDir() {
		os.MkdirAll(parent, 0o755)
	}
	if st, err := os.Stat(out); err == nil && !st.Mode().Perm().Write() {
		return fmt.Errorf("cannot write %s: permission denied", out)
	}
}

Try / catch

if err := closer(); err != nil {
	var pe *fs.PathError
	if errors.As(err, &pe) && errors.Is(pe.Err, syscall.EACCES) {
		// fall back to stdout or a temp file
	}
	return err
}

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Related errors


AI-assisted analysis of alibaba/open-code-review@5cf97d0d15 (2026-09-02). Data as JSON: /api/errors/8f9fdf53f04a227e. Report an issue: GitHub.