{"record":{"id":"3f201f92b2cd7393","repo":"gastownhall/beads","slug":"failed-to-parse-tier1-template-w","errorCode":null,"errorMessage":"failed to parse tier1 template: %w","messagePattern":"failed to parse tier1 template: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/compact/haiku.go","lineNumber":64,"sourceCode":"// newHaikuClient creates a new Haiku API client.\n// API key resolution order: ANTHROPIC_API_KEY env var > MINIMAX_API_KEY env var > ai.api_key config > explicit apiKey parameter.\nfunc newHaikuClient(apiKey string) (*haikuClient, error) {\n\tapiKey, keySource := config.ResolveAIAPIKey(apiKey)\n\tif apiKey == \"\" {\n\t\treturn nil, fmt.Errorf(\"%w: set ANTHROPIC_API_KEY, MINIMAX_API_KEY, or ai.api_key in config\", errAPIKeyRequired)\n\t}\n\n\tclientOptions := []option.RequestOption{option.WithAPIKey(apiKey)}\n\tbaseURL := config.DefaultAIBaseURL(keySource)\n\tif baseURL != \"\" {\n\t\tclientOptions = append(clientOptions, option.WithBaseURL(baseURL))\n\t}\n\n\tclient := anthropic.NewClient(clientOptions...)\n\n\ttier1Tmpl, err := template.New(\"tier1\").Parse(tier1PromptTemplate)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"failed to parse tier1 template: %w\", err)\n\t}\n\n\taiMetricsOnce.Do(initAIMetrics)\n\n\treturn &haikuClient{\n\t\tclient:         client,\n\t\tmodel:          config.DefaultAIModelFor(keySource),\n\t\tapiKeySource:   keySource,\n\t\tbaseURL:        baseURL,\n\t\ttier1Template:  tier1Tmpl,\n\t\tmaxRetries:     maxRetries,\n\t\tinitialBackoff: initialBackoff,\n\t}, nil\n}\n\n// SummarizeTier1 creates a structured summary of an issue (Summary, Key Decisions, Resolution).\nfunc (h *haikuClient) SummarizeTier1(ctx context.Context, issue *types.Issue) (string, error) {\n\tprompt, err := h.renderTier1Prompt(issue)","sourceCodeStart":46,"sourceCodeEnd":82,"githubUrl":"https://github.com/gastownhall/beads/blob/71377f276968b452ee607177637970a4ff888584/internal/compact/haiku.go#L46-L82","documentation":"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.","triggerScenarios":"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).","commonSituations":"Local patches to tier1PromptTemplate introducing template syntax errors; merge conflicts in haiku.go resolved incorrectly; binary built from a broken branch.","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"],"exampleFix":"// before\ntier1PromptTemplate := `Summarize: {{ .Title` // missing closing braces\n// after\ntier1PromptTemplate := `Summarize: {{ .Title }}`","handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"client, err := compact.New(key)\nif err != nil {\n\treturn fmt.Errorf(\"compact client init failed (template/build problem): %w\", err)\n}","preventionTips":["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"],"tags":["template","configuration","internal"],"backgroundTag":"template-parse-failed","analyzedSha":"71377f276968b452ee607177637970a4ff888584","analyzedAt":"2026-08-30T18:55:39.744Z","schemaVersion":2},"datasetVersion":"2026-08-30T23:17:21.991Z"}