charmbracelet/crush · error
parsing template: %w
Error message
parsing template: %w
What it means
Prompt.Build parses the prompt's embedded Go template string with text/template before rendering; this error wraps any template syntax error (bad actions, unclosed {{}}, undefined functions). Because templates are compiled from p.template at build time, it almost always indicates corrupted or hand-edited template content rather than a runtime data problem.
Source
Thrown at internal/agent/prompt/prompt.go:85
}
}
func NewPrompt(name, promptTemplate string, opts ...Option) (*Prompt, error) {
p := &Prompt{
name: name,
template: promptTemplate,
now: time.Now,
}
for _, opt := range opts {
opt(p)
}
return p, nil
}
func (p *Prompt) Build(ctx context.Context, provider, model string, store *config.ConfigStore) (string, error) {
t, err := template.New(p.name).Parse(p.template)
if err != nil {
return "", fmt.Errorf("parsing template: %w", err)
}
var sb strings.Builder
d, err := p.promptData(ctx, provider, model, store)
if err != nil {
return "", err
}
if err := t.Execute(&sb, d); err != nil {
return "", fmt.Errorf("executing template: %w", err)
}
return sb.String(), nil
}
func processFile(filePath string) *ContextFile {
content, err := os.ReadFile(filePath)
if err != nil {
return nil
}View on GitHub (pinned to 7944b8e522)
Solutions
- Read the wrapped text/template error which names the template and line number; fix the syntax at that line in the corresponding internal/agent/templates/*.md.tpl source.
- Check for unbalanced {{ }} delimiters and missing `end` for if/range/block actions.
- If the template calls a custom function, register it with t.Funcs(template.FuncMap{...}) before Parse — note Build parses directly from p.template, so the function must have been included where the template string was assembled.
- Add a unit test that Parses every template at init/startup to surface this error before runtime.
Example fix
// before
const coderTemplate = `You are coding. {{ if .LSP }}LSP enabled{{ }}` // invalid action
// after
const coderTemplate = `You are coding. {{ if .LSP }}LSP enabled{{ end }}` Defensive patterns
Strategy: validation
Validate before calling
if _, err := template.New("check").Parse(promptTemplateSource); err != nil {
panic(fmt.Sprintf("prompt template invalid: %v", err))
} Type guard
func templateOK(name, src string, funcs template.FuncMap) bool {
t := template.New(name)
if len(funcs) > 0 { t = t.Funcs(funcs) }
return t.Parse(src) == nil
} Try / catch
out, err := p.Build(ctx, provider, model, store)
if err != nil {
var tErr error
if strings.HasPrefix(err.Error(), "parsing template:") {
return fmt.Errorf("prompt %q has invalid template syntax: %w", p.name, err)
}
return out, err
} Prevention
- Add a test that Parses every template in internal/agent/templates at CI time so syntax errors never reach runtime.
- Register all helper functions before parsing; never reference Funcs-only names without adding them to the FuncMap.
- Keep .md.tpl edits minimal and run go test after every prompt change.
- If templates come from user config, escape or validate literal `{{` sequences before passing them through.
When it happens
Trigger: p.template contains invalid template syntax, e.g. `{{ if .X }` (missing end), `{{ end }}` without `{{ if }}`, or a call to an unregistered function like `{{ bolder .Foo }}` that was never added via template.New(...).Funcs(...).
Common situations: A developer edits an internal .md.tpl prompt template and introduces a typo; a new template helper function is referenced in the template but not registered on the template before Parse; template text loaded from user config contains stray `{{` sequences.
Related errors
- error creating prompt: %s
- executing template: %w
- unsupported by the running server
- clipboard operations are not supported on this platform
- clipboard is empty or holds an unsupported format
AI-assisted analysis of charmbracelet/crush@7944b8e522 (2026-08-29).
Data as JSON: /api/errors/660fe6dec901e9da.
Report an issue: GitHub.