charmbracelet/crush · error
failed to generate HTML: %w
Error message
failed to generate HTML: %w
What it means
`crush stats` renders the gathered statistics into an HTML report at <dataDir>/stats/index.html. This error wraps any failure inside generateHTML (template execution or file creation/write). The wrapped error tells whether it was a template rendering issue or an I/O problem.
Source
Thrown at internal/cmd/stats.go:230
return fmt.Errorf("failed to get current directory: %w", err)
}
projName = strings.Replace(project, currentUser.HomeDir, "~", 1)
}
outputDataDir := dataDir
if outputDataDir == "" {
cfg, err := config.Init("", "", false)
if err == nil {
outputDataDir = cfg.Config().Options.DataDirectory
}
}
if outputDataDir == "" {
outputDataDir = ".crush"
}
htmlPath := filepath.Join(outputDataDir, "stats/index.html")
if err := generateHTML(mergedStats, projectStats, projName, username, htmlPath); err != nil {
return fmt.Errorf("failed to generate HTML: %w", err)
}
fmt.Printf("Stats generated: %s\n", htmlPath)
if err := browser.OpenFile(htmlPath); err != nil {
fmt.Printf("Could not open browser: %v\n", err)
fmt.Println("Please open the file manually.")
}
return nil
}
// crawlForStats crawls a directory recursively looking for .crush/crush.db files.
func crawlForStats(ctx context.Context, rootDir string) ([]ProjectStats, error) {
var dbPaths []struct {
dbPath string
projectDir string
}View on GitHub (pinned to 7944b8e522)
Solutions
- Check that the data dir (default .crush) is writable: `ls -ld .crush` and fix permissions
- Verify free disk space with `df -h`
- If using a custom --data-dir, ensure the path exists or can be created and is writable
- Run `crush stats` from a directory where you own .crush (fix ownership with chown)
Example fix
// before mkdir /protected && crush stats --data-dir /protected/out # permission denied // after mkdir -p ~/crush-stats && crush stats --data-dir ~/crush-stats
Defensive patterns
Strategy: try-catch
Validate before calling
datadir="${CRUSH_DATA_DIR:-.crush}"
if [ ! -w "$datadir" ]; then
echo "Data dir $datadir is not writable" >&2
exit 1
fi
if [ "$(df -h . | awk 'NR==2{print $5}' | tr -d '%')" -ge 99 ]; then
echo "Disk full; free space before generating stats" >&2
exit 1
fi Try / catch
if err := runStats(...); err != nil {
if errors.Is(err, os.ErrPermission) {
fmt.Fprintln(os.Stderr, "Fix permissions on the stats data dir and retry")
return nil
}
return err // includes template-execution errors via %w
} Prevention
- Ensure the data dir (default .crush) exists and is writable by the running user
- Don't run crush via sudo in a way that leaves root-owned .crush files
- Monitor disk space where the stats HTML is written
- When using a custom --data-dir, pre-create it with correct permissions
- Upgrade crush if template nil-pointer errors persist after data changes
When it happens
Trigger: generateHTML fails to create or write the output file (bad permissions, read-only filesystem, <dataDir>/stats not creatable) or fails while executing the HTML template against mergedStats/projectStats.
Common situations: .crush directory on a read-only mount or owned by another user; disk full; data dir overridden via --data-dir to a path without write permission; corrupted/nil stats triggering template nil-pointer issues.
Related errors
- error reading image file: %w
- error reading file: %w
- failed to tail log file: %v
- failed to change directory: %v
- failed to crawl for stats: %w
AI-assisted analysis of charmbracelet/crush@7944b8e522 (2026-08-29).
Data as JSON: /api/errors/b3374654fa92de6d.
Report an issue: GitHub.