{"record":{"id":"2742b026d504be0b","repo":"charmbracelet/crush","slug":"execute-template-w","errorCode":null,"errorMessage":"execute template: %w","messagePattern":"execute template: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/cmd/stats.go","lineNumber":746,"sourceCode":"\t\tProjectName      string\n\t\tUsername         string\n\t}{\n\t\tStatsJSON:        template.JS(statsJSON),\n\t\tProjectStatsJSON: template.JS(projectStatsJSON),\n\t\tCSS:              template.CSS(statsCSS),\n\t\tJS:               template.JS(statsJS),\n\t\tHeader:           template.HTML(headerSVG),\n\t\tHeartbit:         template.HTML(heartbitSVG),\n\t\tFooter:           template.HTML(footerSVG),\n\t\tFavicon:          template.URL(\"data:image/svg+xml;base64,\" + base64.StdEncoding.EncodeToString([]byte(heartbitSVG))),\n\t\tGeneratedAt:      stats.GeneratedAt.Format(\"2006-01-02\"),\n\t\tProjectName:      projName,\n\t\tUsername:         username,\n\t}\n\n\tvar buf bytes.Buffer\n\tif err := tmpl.Execute(&buf, data); err != nil {\n\t\treturn fmt.Errorf(\"execute template: %w\", err)\n\t}\n\n\t// Ensure parent directory exists.\n\tif err := os.MkdirAll(filepath.Dir(path), 0o755); err != nil {\n\t\treturn fmt.Errorf(\"create directory: %w\", err)\n\t}\n\n\treturn os.WriteFile(path, buf.Bytes(), 0o644)\n}\n","sourceCodeStart":728,"sourceCodeEnd":756,"githubUrl":"https://github.com/charmbracelet/crush/blob/7944b8e52225d8805e31eacbf7ef24856b0dfb7a/internal/cmd/stats.go#L728-L756","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Read the wrapped error: html/template names the failing action/field.","Align the anonymous data struct in generateHTML with the field/method names used in statsTemplate.","Fix any data method that returns an error during render (check what template.Execute reports).","Re-run `crush stats --html` and verify the generated file renders."],"exampleFix":"// before: template uses {{.ProjectStatsJSON}} but struct lacks it\ndata := struct { StatsJSON template.JS }{statsJSON}\n// after\ndata := struct {\n    StatsJSON         template.JS\n    ProjectStatsJSON  template.JS\n}{statsJSON, projectStatsJSON}","handlingStrategy":"validation","validationCode":"// verify the template only references fields that exist on data\nfor _, f := range []string{\"StatsJSON\", \"ProjectStatsJSON\", \"ProjectName\", \"Username\"} {\n    if !strings.Contains(statsTemplate, f) { continue }\n    if !structHasField(data, f) {\n        panic(\"template references missing field: \" + f)\n    }\n}","typeGuard":null,"tryCatchPattern":"var buf bytes.Buffer\nif err := tmpl.Execute(&buf, data); err != nil {\n    // html/template errors name the failing action\n    log.Printf(\"render failed at template action: %v\", err)\n    return fmt.Errorf(\"render stats report: %w\", err)\n}","preventionTips":["Keep the anonymous data struct in sync with statsTemplate after any stats-struct refactor.","Avoid data methods that can return errors; precompute values before Execute.","Test HTML generation locally with `crush stats --html` after template changes.","Nil-check optional values before placing them in the data struct."],"tags":["template","html-template","rendering","cli"],"backgroundTag":"template-execution-error","analyzedSha":"7944b8e52225d8805e31eacbf7ef24856b0dfb7a","analyzedAt":"2026-08-29T12:48:59.079Z","schemaVersion":2},"datasetVersion":"2026-08-29T17:17:51.833Z"}