alibaba/open-code-review · error

close output file: %w

Error message

close output file: %w

What it means

executeScan opens the output destination via resolveOutputWriter and registers a deferred close. If closing the output file fails (flush error, disk full, permission loss), the error is joined into the returned error as "close output file". The scan result itself may have succeeded, but the output could be incomplete or unwritable.

Source

Thrown at cmd/opencodereview/scan_cmd.go:118

	parts := strings.Split(raw, ",")
	out := make([]string, 0, len(parts))
	for _, p := range parts {
		p = strings.TrimSpace(p)
		if p != "" {
			out = append(out, p)
		}
	}
	return out
}

func executeScan(opts scanOptions) (retErr error) {
	out, closeOut, err := resolveOutputWriter(opts.outputPath, opts.outputFormat)
	if err != nil {
		return err
	}
	defer func() {
		if cerr := closeOut(); cerr != nil {
			retErr = errors.Join(retErr, fmt.Errorf("close output file: %w", cerr))
		}
	}()

	cc, err := loadCommonContext(opts.repoDir, opts.rulePath, "", opts.maxTools, opts.maxGitProcs, false)
	if err != nil {
		return err
	}
	applyCLIExcludes(cc, splitPaths(opts.excludes))

	// scan owns its own template (scan_template.json) independent from the
	// diff-review template loaded by loadCommonContext above. Apply --max-tools
	// as an "only raise" override to the scan template's per-file budget.
	scanTpl, err := template.LoadScanDefault()
	if err != nil {
		return fmt.Errorf("load scan template: %w", err)
	}
	if err := scanTpl.Validate(); err != nil {
		return fmt.Errorf("invalid scan template: %w", err)

View on GitHub (pinned to 5cf97d0d15)

Solutions

  1. Check disk space (`df -h`) on the volume holding the output file.
  2. Verify write permissions on the output path; write to a local directory instead of a network mount.
  3. Inspect the joined error — the wrapped cause identifies the OS-level close failure.
  4. Re-run the scan after freeing space/fixing the mount, since the output file may be truncated.

Example fix

// before
ocr scan --output /mnt/nfs/scan-results.json   # NFS flaky
// after
ocr scan --output ./scan-results.json && cp scan-results.json /mnt/nfs/
Defensive patterns

Strategy: try-catch

Validate before calling

if st, err := os.Stat(filepath.Dir(outputPath)); err != nil || !st.IsDir() {
    return errors.New("output directory unwritable")
}
if err := checkDiskFree(filepath.Dir(outputPath), 10<<20); err != nil {
    return err
}

Try / catch

if err := executeScan(opts); err != nil {
    var joinErr interface{ Unwrap() []error }
    if errors.As(err, &joinErr) { /* inspect joined close error */ }
    if strings.Contains(err.Error(), "close output file") {
        // scan may have completed; verify output file before discarding
    }
    return err
}

Prevention

When it happens

Trigger: `ocr scan --output <file>` where closing the file at the end fails: disk full while flushing buffered output, file permissions changed mid-run, or NFS/network filesystem errors on close.

Common situations: Writing scan output to a full disk or quota-exceeded volume; output on a flaky network mount; stdout redirected to a closed pipe.

Related errors


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