{"record":{"id":"4ed1d2ab7c46d696","repo":"gastownhall/beads","slug":"issue-s-is-not-eligible-for-tier-1-compaction","errorCode":null,"errorMessage":"issue %s is not eligible for Tier 1 compaction","messagePattern":"issue (.+?) is not eligible for Tier 1 compaction","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"internal/compact/compactor.go","lineNumber":102,"sourceCode":"\t}, nil\n}\n\n// CompactTier1 compacts a single issue at Tier 1 (basic summarization).\nfunc (c *Compactor) CompactTier1(ctx context.Context, issueID string) error {\n\tif ctx.Err() != nil {\n\t\treturn ctx.Err()\n\t}\n\n\t// Check eligibility before fetching issue (fail fast)\n\teligible, reason, err := c.store.CheckEligibility(ctx, issueID, 1)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"failed to verify eligibility: %w\", err)\n\t}\n\tif !eligible {\n\t\tif reason != \"\" {\n\t\t\treturn fmt.Errorf(\"issue %s is not eligible for Tier 1 compaction: %s\", issueID, reason)\n\t\t}\n\t\treturn fmt.Errorf(\"issue %s is not eligible for Tier 1 compaction\", issueID)\n\t}\n\n\tissue, err := c.store.GetIssue(ctx, issueID)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"failed to fetch issue: %w\", err)\n\t}\n\n\t// Calculate original size\n\toriginalSize := len(issue.Description) + len(issue.Design) + len(issue.Notes) + len(issue.AcceptanceCriteria)\n\n\tif c.config.DryRun {\n\t\treturn fmt.Errorf(\"dry-run: would compact %s (original size: %d bytes)\", issueID, originalSize)\n\t}\n\n\t// Get summary from AI\n\tsummary, err := c.summarizer.SummarizeTier1(ctx, issue)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"failed to summarize: %w\", err)","sourceCodeStart":84,"sourceCodeEnd":120,"githubUrl":"https://github.com/gastownhall/beads/blob/71377f276968b452ee607177637970a4ff888584/internal/compact/compactor.go#L84-L120","documentation":"Same policy rejection as the reasoned variant, but CheckEligibility returned eligible=false with an empty reason, so only the generic ineligibility message is produced. The store declined the compaction without explaining why.","triggerScenarios":"Calling CompactTier1 on an issue where store.CheckEligibility(ctx, issueID, 1) returns (false, \"\", nil) — the default rejection path when the store provides no detailed reason.","commonSituations":"Storage backends that implement eligibility checks but return no reason string; older store implementations without detailed reason reporting; issue fails a rule the backend does not describe.","solutions":["Check the issue's state/size/compaction history manually to determine why it was rejected","Call CheckEligibility directly to confirm the (bool, string) return values","Upgrade or fix the store implementation so it populates the reason string","Treat as a benign skip in batch workflows"],"exampleFix":null,"handlingStrategy":"validation","validationCode":"eligible, reason, err := store.CheckEligibility(ctx, issueID, 1)\nif err == nil && !eligible {\n    // inspect the issue manually: closed? already compacted? too small?\n    iss, _ := store.GetIssue(ctx, issueID)\n    log.Printf(\"skip %s (reason empty, status=%v)\", issueID, iss)\n}","typeGuard":null,"tryCatchPattern":"if err := c.CompactTier1(ctx, id); err != nil {\n    if strings.Contains(err.Error(), \"not eligible for Tier 1 compaction\") {\n        return nil\n    }\n    return err\n}","preventionTips":["Pre-check eligibility in batch scripts so generic rejections are expected","Don't assume the reason will be populated — handle empty reasons in your store","Inspect issue state directly when the store gives no explanation"],"tags":["go","validation","eligibility","policy"],"backgroundTag":"compaction-ineligible","analyzedSha":"71377f276968b452ee607177637970a4ff888584","analyzedAt":"2026-08-30T18:55:39.744Z","schemaVersion":2},"datasetVersion":"2026-08-30T23:17:21.991Z"}