gastownhall/beads · error
failed to parse tier1 template: %w
Error message
failed to parse tier1 template: %w
What it means
newHaikuClient parses the built-in Go text/template tier1PromptTemplate at construction time. This is a compile-time-invariant template embedded in the binary, so a parse failure indicates the internal prompt template constant is malformed — practically only possible with a corrupted build or a modified/patched binary.
Source
Thrown at internal/compact/haiku.go:64
// newHaikuClient creates a new Haiku API client.
// API key resolution order: ANTHROPIC_API_KEY env var > MINIMAX_API_KEY env var > ai.api_key config > explicit apiKey parameter.
func newHaikuClient(apiKey string) (*haikuClient, error) {
apiKey, keySource := config.ResolveAIAPIKey(apiKey)
if apiKey == "" {
return nil, fmt.Errorf("%w: set ANTHROPIC_API_KEY, MINIMAX_API_KEY, or ai.api_key in config", errAPIKeyRequired)
}
clientOptions := []option.RequestOption{option.WithAPIKey(apiKey)}
baseURL := config.DefaultAIBaseURL(keySource)
if baseURL != "" {
clientOptions = append(clientOptions, option.WithBaseURL(baseURL))
}
client := anthropic.NewClient(clientOptions...)
tier1Tmpl, err := template.New("tier1").Parse(tier1PromptTemplate)
if err != nil {
return nil, fmt.Errorf("failed to parse tier1 template: %w", err)
}
aiMetricsOnce.Do(initAIMetrics)
return &haikuClient{
client: client,
model: config.DefaultAIModelFor(keySource),
apiKeySource: keySource,
baseURL: baseURL,
tier1Template: tier1Tmpl,
maxRetries: maxRetries,
initialBackoff: initialBackoff,
}, nil
}
// SummarizeTier1 creates a structured summary of an issue (Summary, Key Decisions, Resolution).
func (h *haikuClient) SummarizeTier1(ctx context.Context, issue *types.Issue) (string, error) {
prompt, err := h.renderTier1Prompt(issue)View on GitHub (pinned to 71377f2769)
Solutions
- Check the tier1PromptTemplate constant for unbalanced or malformed {{ }} template actions
- Rebuild from a clean checkout of upstream main
- Run `go test ./internal/compact/...` — TestNewHaikuClient tests will reproduce the parse failure instantly
- If you patched the template, validate the syntax with template.Must in a scratch program
Example fix
// before
tier1PromptTemplate := `Summarize: {{ .Title` // missing closing braces
// after
tier1PromptTemplate := `Summarize: {{ .Title }}` Defensive patterns
Strategy: try-catch
Try / catch
client, err := compact.New(key)
if err != nil {
return fmt.Errorf("compact client init failed (template/build problem): %w", err)
} Prevention
- Build from clean upstream source; avoid hand-editing tier1PromptTemplate
- Run `go test ./internal/compact/...` after any changes to template constants
- Validate template syntax with template.Must during development
When it happens
Trigger: template.New("tier1").Parse(tier1PromptTemplate) fails while constructing the haiku client — only when the embedded template source is invalid (broken {{...}} action syntax in the package constant).
Common situations: Local patches to tier1PromptTemplate introducing template syntax errors; merge conflicts in haiku.go resolved incorrectly; binary built from a broken branch.
Understand the failure class
- Parsing and encoding errors: unexpected token, malformed input — why parsers reject input and how to find the real culprit.
Related errors
- multiple .doltcfg directories detected
- dolt directory is required
- httpapi: a configured role fires this workspace's hooks; thi
- httpapi: the configured provider fires this workspace's hook
- httpapi: this server has no unit-of-work provider; it answer
AI-assisted analysis of gastownhall/beads@71377f2769 (2026-08-30).
Data as JSON: /api/errors/3f201f92b2cd7393.
Report an issue: GitHub.