charmbracelet/crush · error

execute template: %w

Error message

execute template: %w

What it means

generateHTML wraps an error returned by tmpl.Execute(&buf, data), which renders the parsed stats template into a buffer. html/template Execute fails on template issues detected at runtime: calling an undefined method/field on the data struct, a data method returning an error, a nil pointer dereference in an action, or writing to the writer failing.

Source

Thrown at internal/cmd/stats.go:746

		ProjectName      string
		Username         string
	}{
		StatsJSON:        template.JS(statsJSON),
		ProjectStatsJSON: template.JS(projectStatsJSON),
		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. Read the wrapped error: html/template names the failing action/field.
  2. Align the anonymous data struct in generateHTML with the field/method names used in statsTemplate.
  3. Fix any data method that returns an error during render (check what template.Execute reports).
  4. Re-run `crush stats --html` and verify the generated file renders.

Example fix

// before: template uses {{.ProjectStatsJSON}} but struct lacks it
data := struct { StatsJSON template.JS }{statsJSON}
// after
data := struct {
    StatsJSON         template.JS
    ProjectStatsJSON  template.JS
}{statsJSON, projectStatsJSON}
Defensive patterns

Strategy: validation

Validate before calling

// verify the template only references fields that exist on data
for _, f := range []string{"StatsJSON", "ProjectStatsJSON", "ProjectName", "Username"} {
    if !strings.Contains(statsTemplate, f) { continue }
    if !structHasField(data, f) {
        panic("template references missing field: " + f)
    }
}

Try / catch

var buf bytes.Buffer
if err := tmpl.Execute(&buf, data); err != nil {
    // html/template errors name the failing action
    log.Printf("render failed at template action: %v", err)
    return fmt.Errorf("render stats report: %w", err)
}

Prevention

When it happens

Trigger: Calling generateHTML where the template references a field/function absent from the anonymous data struct (e.g. after renaming a Stats field without updating the template), or a data method returns an error.

Common situations: Refactoring the stats structs (StatsJSON, ProjectName, Username, etc.) without updating statsTemplate; a method on the data returning an error mid-render; an unexpected nil value in the data map.

Related errors


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