grafana/k6 · error

error writing error message to stderr: %w

Error message

error writing error message to stderr: %w

What it means

The rarest error in `k6 new`: inside the deferred close of the newly created script file, the file failed to close AND writing the close-error message to stderr also failed, so the original close error is replaced by this stderr-write failure. It signals a deeply broken I/O environment (both the target file descriptor and stderr unusable), not a template or usage problem.

Source

Thrown at internal/cmd/new.go:79

		ProjectID:  c.projectID,
	}

	// First render the template to a buffer to validate it
	var buf strings.Builder
	if err := templates.ExecuteTemplate(&buf, tmpl, argsStruct); err != nil {
		return fmt.Errorf("failed to execute template %s: %w", c.templateType, err)
	}

	// Only create the file after template rendering succeeds
	fd, err := c.gs.FS.Create(target)
	if err != nil {
		return err
	}

	defer func() {
		if cerr := fd.Close(); cerr != nil {
			if _, werr := fmt.Fprintf(c.gs.Stderr, "error closing file: %v\n", cerr); werr != nil {
				err = fmt.Errorf("error writing error message to stderr: %w", werr)
			} else {
				err = cerr
			}
		}
	}()

	// Write the rendered content to the file
	if _, err := io.WriteString(fd, buf.String()); err != nil {
		return err
	}

	if _, err := fmt.Fprintf(c.gs.Stdout, "New script created: %s (%s template).\n", target, c.templateType); err != nil {
		return err
	}

	return nil
}

View on GitHub (pinned to 93accf6570)

Solutions

  1. Restore a working stderr (don't run with 2>&-; ensure the consuming pipe stays open) and re-run
  2. Check fd limits and I/O health: `ulimit -n`, disk space, and mount status of the target directory
  3. Verify the target file's state afterwards (size, readability) — with both errors the file may be incompletely closed but its content was already written via io.WriteString
  4. If it recurs only under a specific supervisor/wrapper, run k6 directly once to isolate the environment issue
Defensive patterns

Strategy: fallback

Validate before calling

# Ensure stderr is a writable fd before running k6 (guard the double-failure path)
if ! : 2>/dev/null; then echo 'stderr closed'; exit 1; fi
ulimit -n 1024 >/dev/null 2>&1 || true   # sane fd ceiling for wrapper processes
k6 new script.js

Try / catch

#k6 new script.js || {
#  echo 'k6 new failed; check stderr pipe and fd limits' >&2
#  exit 1
#}

Prevention

When it happens

Trigger: stderr is closed or points to an exhausted descriptor/pipe (e.g. `k6 new s.js 2>&-`, or a parent process that closed its read end of the stderr pipe) while the created file also fails to close (fd pressure, NFS/overlayfs issues, disk detachment).

Common situations: Malformed process supervision setups that close stderr; sandboxed containers with fd limits (ulimit -n) exhausted; running under wrappers that pipe stderr into a process that exits early.

Related errors


AI-assisted analysis of grafana/k6@93accf6570 (2026-08-15). Data as JSON: /api/errors/bc49c00622fd7d57. Report an issue: GitHub.