charmbracelet/crush · error

executing template: %w

Error message

executing template: %w

What it means

Prompt.Build renders the agent's Go text/template system prompt with runtime data (provider, model, context files, environment). This error wraps any failure returned by template.Execute, meaning the template itself parsed fine but the engine failed while writing output — typically because a called method/field on the data struct errored, a nested template or function lookup failed at runtime, or the output writer errored.

Source

Thrown at internal/agent/prompt/prompt.go:93

	}
	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
	}
	return &ContextFile{
		Path:    filePath,
		Content: string(content),
	}
}

func processContextPath(p string, store *config.ConfigStore) []ContextFile {
	var contexts []ContextFile

View on GitHub (pinned to 7944b8e522)

Solutions

  1. Check the wrapped error (%w cause) — it names the exact template node/function that failed at runtime
  2. If you supply a custom prompt template, compare it against the current internal/agent/templates/*.md.tpl for renamed functions or fields
  3. Upgrade/repair any embedded template so every {{template "name"}} reference matches a defined template
  4. If the cause is a writer error on strings.Builder (rare), verify memory/panel limits; otherwise treat as a code/template mismatch

Example fix

// before: template references undefined function
{{ .Now.Format }} ...
// after: call an existing field/method provided by promptData
{{ .CurrentTime.Format "2006-01-02" }} ...
Defensive patterns

Strategy: try-catch

Validate before calling

// Pre-check in Go before Build
if strings.Contains(template, "{{template ") {
    // ensure referenced templates are registered
}
_, err := template.New(name).Funcs(funcs).Parse(tmpl)
if err != nil { return fmt.Errorf("template parse failed: %w", err) }

Type guard

func hasTemplate(t *template.Template, name string) bool {
    for _, tt := range t.Templates() {
        if tt.Name() == name { return true }
    }
    return false
}

Try / catch

out, err := p.Build(ctx, provider, model, store)
if err != nil {
    var perr *template.Error
    if errors.As(err, &perr) {
        log.Printf("template %s failed at exec: %v", perr.TemplateName, perr)
    }
    return fmt.Errorf("prompt build failed: %w", err)
}

Prevention

When it happens

Trigger: Calling Build (or InitializePrompt/coderAgent which call it) when the template body invokes a method or pipeline step on promptData that returns an error at execution time, references a missing nested template via {{template ...}}, or a registered template FuncMap function fails. Parse succeeds (prompt.go:83) but Execute (prompt.go:92) fails.

Common situations: A custom or stale prompt template overriding the built-in one calls functions that don't exist in the current binary version; context-file data produces a nil pointer inside a template method; embedding a template name that was never defined after upgrading.

Related errors


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