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

  1. 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.
  2. Check for unbalanced {{ }} delimiters and missing `end` for if/range/block actions.
  3. 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.
  4. 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

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


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