charmbracelet/crush · error

failed to create stderr log file: %v

Error message

failed to create stderr log file: %v

What it means

Immediately after creating stdout.log, startDetachedServer creates <chDir>/stderr.log to capture the detached server's stderr. A failure here is wrapped as 'failed to create stderr log file' and aborts the spawn, mirroring the stdout failure path.

Source

Thrown at internal/cmd/root.go:889

	// Use context.Background() so the parent's context cancellation does not
	// kill the spawned server. detachProcess (Setsid on !windows,
	// DETACHED_PROCESS on windows) is what truly detaches the child from
	// this process's lifetime.
	c := exec.CommandContext(context.Background(), exe, cmdArgs...)
	stdoutPath := filepath.Join(chDir, "stdout.log")
	stderrPath := filepath.Join(chDir, "stderr.log")
	detachProcess(c)

	stdout, err := os.Create(stdoutPath)
	if err != nil {
		return fmt.Errorf("failed to create stdout log file: %v", err)
	}
	defer stdout.Close()
	c.Stdout = stdout

	stderr, err := os.Create(stderrPath)
	if err != nil {
		return fmt.Errorf("failed to create stderr log file: %v", err)
	}
	defer stderr.Close()
	c.Stderr = stderr

	if err := c.Start(); err != nil {
		return fmt.Errorf("failed to start crush server: %v", err)
	}

	if err := c.Process.Release(); err != nil {
		return fmt.Errorf("failed to detach crush server process: %v", err)
	}

	return nil
}

func shouldEnableMetrics(cfg *config.Config) bool {
	if v, _ := strconv.ParseBool(os.Getenv("CRUSH_DISABLE_METRICS")); v {
		return false

View on GitHub (pinned to 7944b8e522)

Solutions

  1. Check free disk space and inodes (df; df -i) — two consecutive create failures usually mean exhaustion.
  2. Fix permissions/ownership on the per-host server directory.
  3. Remove a stray directory or immutable file at the stderr.log path (ls -la, chattr -i if needed).
  4. Rotate/clean old stdout.log and stderr.log files that may be consuming the quota.
Defensive patterns

Strategy: validation

Validate before calling

if err := checkFreeDisk(chDir, 10*1024*1024); err != nil {
	return fmt.Errorf("insufficient space for server logs: %w", err)
}
if info, err := os.Lstat(filepath.Join(chDir, "stderr.log")); err == nil && info.IsDir() {
	return fmt.Errorf("stderr.log path is a directory")
}

Prevention

When it happens

Trigger: os.Create(stderrPath) fails for the same class of reasons as stdout.log: unwritable directory, full disk/quota, path component conflict, or sandbox blocking writes — typically right after stdout.log succeeded, so failures here are usually resource exhaustion that hit between the two creates.

Common situations: Disk filling up between the two os.Create calls (giant logs); inode exhaustion; security tooling racing file creation; the stderr.log path existing as a directory.

Related errors


AI-assisted analysis of charmbracelet/crush@7944b8e522 (2026-08-29). Data as JSON: /api/errors/835518637062037a. Report an issue: GitHub.