charmbracelet/crush · error

create directory: %w

Error message

create directory: %w

What it means

generateHTML wraps an error from os.MkdirAll(filepath.Dir(path), 0o755), which creates the parent directory for the output HTML file before writing it. It fails when the directory cannot be created: permission denied on the target path, a non-directory file already occupying a path component, or an invalid path.

Source

Thrown at internal/cmd/stats.go:751

		CSS:              template.CSS(statsCSS),
		JS:               template.JS(statsJS),
		Header:           template.HTML(headerSVG),
		Heartbit:         template.HTML(heartbitSVG),
		Footer:           template.HTML(footerSVG),
		Favicon:          template.URL("data:image/svg+xml;base64," + base64.StdEncoding.EncodeToString([]byte(heartbitSVG))),
		GeneratedAt:      stats.GeneratedAt.Format("2006-01-02"),
		ProjectName:      projName,
		Username:         username,
	}

	var buf bytes.Buffer
	if err := tmpl.Execute(&buf, data); err != nil {
		return fmt.Errorf("execute template: %w", err)
	}

	// Ensure parent directory exists.
	if err := os.MkdirAll(filepath.Dir(path), 0o755); err != nil {
		return fmt.Errorf("create directory: %w", err)
	}

	return os.WriteFile(path, buf.Bytes(), 0o644)
}

View on GitHub (pinned to 7944b8e522)

Solutions

  1. Check the wrapped error for the offending path component and errno (EACCES, ENOTDIR).
  2. Write the report to a directory you own (e.g. project dir or ~/), not a protected system path.
  3. Remove/rename any regular file that occupies a directory position in the output path.
  4. Verify the filesystem is writable (not read-only, disk not full).

Example fix

// before
crush stats --html --output /root/reports/stats.html // permission denied
// after
crush stats --html --output ./reports/stats.html
Defensive patterns

Strategy: validation

Validate before calling

dir := filepath.Dir(path)
if info, err := os.Stat(dir); err == nil && !info.IsDir() {
    return fmt.Errorf("%s exists and is not a directory", dir)
}
if err := unix.Access(filepath.Dir(dir), unix.W_OK); err != nil {
    return fmt.Errorf("no write permission for %s", dir)
}

Try / catch

if err := os.MkdirAll(filepath.Dir(path), 0o755); err != nil {
    return fmt.Errorf("cannot create output directory %s: %w", filepath.Dir(path), err)
}

Prevention

When it happens

Trigger: Calling generateHTML with an output path whose parent directory cannot be created — e.g. writing under a root-owned directory without sudo, a file named like the target directory exists, or a malformed path.

Common situations: Passing --output to a location like /usr/share/... or another user's home without write permission; the output flag pointing inside a path occupied by a regular file; read-only mount or full disk.

Related errors


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