wagoodman/dive · error

cannot open export file: %w

Error message

cannot open export file: %w

What it means

Returned when afero's OpenFile(path, O_RDWR|O_CREATE, 0644) fails while creating/truncating the export target file. The path comes directly from the --json flag (opts.Export.JsonPath). This wraps ordinary filesystem errors: a directory in the path that does not exist, permission denied, or the target being a directory.

Source

Thrown at cmd/dive/cli/internal/command/adapter/exporter.go:54

			OnSuccess:    "Exported details",
		},
		HideOnSuccess:      false,
		HideStageOnSuccess: false,
		ID:                 analysis.Image,
		Context:            fmt.Sprintf("[file: %s]", path),
	})

	bytes, err := export.NewExport(analysis).Marshal()
	if err != nil {
		mon.SetError(err)
		return fmt.Errorf("cannot marshal export payload: %w", err)
	} else {
		mon.SetCompleted()
	}

	file, err := e.filesystem.OpenFile(path, os.O_RDWR|os.O_CREATE, 0644)
	if err != nil {
		return fmt.Errorf("cannot open export file: %w", err)
	}
	defer file.Close()

	_, err = file.Write(bytes)
	if err != nil {
		return fmt.Errorf("cannot write to export file: %w", err)
	}
	return nil
}

View on GitHub (pinned to d6c691947f)

Solutions

  1. Check the wrapped error (the %w part) — it names the exact OS-level cause
  2. Create the parent directory first: mkdir -p $(dirname <path>) or ensure the CI job creates the artifacts dir
  3. Verify write permission on the target directory and that the path is not an existing directory
  4. Use an absolute path in scripts to avoid cwd-relative surprises

Example fix

# before
dive nginx:latest --json artifacts/report.json  # artifacts/ does not exist

# after
mkdir -p artifacts && dive nginx:latest --json artifacts/report.json
Defensive patterns

Strategy: validation

Validate before calling

// ensure the parent directory and a regular-file target before exporting
if dir := filepath.Dir(path); dir != "" {
    if err := os.MkdirAll(dir, 0o755); err != nil { return err }
}
if fi, err := os.Stat(path); err == nil && fi.IsDir() { return fmt.Errorf("export path is a directory: %s", path) }

Try / catch

if err := exporter.ExportTo(ctx, analysis, path); err != nil {
    if strings.Contains(err.Error(), "cannot open export file") {
        // filesystem problem: check dir existence + permissions, then retry once after MkdirAll
    }
    return err
}

Prevention

When it happens

Trigger: Running dive image --json /nonexistent-dir/report.json (parent dir missing), --json into a read-only location, --json / (path is a directory), or when the process lacks write permission on the target directory.

Common situations: CI pipelines writing --json into an artifact directory that the build step never created (mkdir -p forgotten); running as a user without write access to the given path; typo'd path with a missing intermediate directory.

Related errors


AI-assisted analysis of wagoodman/dive@d6c691947f (2026-08-15). Data as JSON: /api/errors/f353cc00f6e22315. Report an issue: GitHub.