grafana/k6 · error

could not open

Error message

could not open '%s': %w

What it means

A handleSummary() (or --summary-export style) result can write to files: for any key other than 'stdout'/'stderr', k6 opens the path with O_WRONLY|O_CREAT|O_TRUNC (mode 0666). If the open fails — missing parent directory, no permission, read-only filesystem, path is a directory — the failure is wrapped as 'could not open <path>'. Multiple failures are consolidated under 'Could not save some summary information:'. Note the file is truncated if it already exists.

Solutions

  1. Create the target directory before the run: mkdir -p reports
  2. Use an absolute, writable path, or the special 'stdout'/'stderr' keys
  3. Check directory permissions for the user running k6 — it needs write+create on the directory, and remember an existing file gets truncated

Example fix

# before
# script: return { './reports/summary.json': JSON.stringify(data) } — reports/ missing

# after
mkdir -p reports && k6 run script.js
# or write next to cwd: return { 'summary.json': JSON.stringify(data) }
Defensive patterns

Strategy: validation

Validate before calling

# ensure every summary destination directory exists and is writable
for d in reports out/summary; do
  mkdir -p "$d" || exit 1
  [ -w "$d" ] || { echo "$d is not writable" >&2; exit 1; }
done
k6 run script.js

Prevention

When it happens

Trigger: handleSummary returning { 'reports/summary.json': ... } when reports/ does not exist; writing into a directory the k6 process cannot modify; read-only container filesystem; key path pointing at a directory.

Common situations: Summary templates from blog posts/docs writing into subdirectories that CI never creates; containers with read-only mounts; first run in a fresh checkout.

Related errors


AI-assisted analysis of grafana/k6@3fcf5388d7 (2026-08-18). Data as JSON: /api/errors/6b3414b9abfd9ca4. Report an issue: GitHub.

Appendix: source

Thrown at internal/cmd/run.go:607

}

func handleSummaryResult(fs fsext.Fs, stdOut, stdErr io.Writer, result map[string]io.Reader) error {
	var errs []error

	getWriter := func(path string) (io.Writer, error) {
		switch path {
		case "stdout":
			return stdOut, nil
		case "stderr":
			return stdErr, nil
		default:
			return fs.OpenFile(path, syscall.O_WRONLY|syscall.O_CREAT|syscall.O_TRUNC, 0o666)
		}
	}

	for path, value := range result {
		if writer, err := getWriter(path); err != nil {
			errs = append(errs, fmt.Errorf("could not open '%s': %w", path, err))
		} else if n, err := io.Copy(writer, value); err != nil {
			errs = append(errs, fmt.Errorf("error saving summary to '%s' after %d bytes: %w", path, n, err))
		}
	}

	return consolidateErrorMessage(errs, "Could not save some summary information:")
}

View on GitHub (pinned to 3fcf5388d7)