{"record":{"id":"bd15330713052f62","repo":"gastownhall/beads","slug":"worktree-head-is-not-contained-in-the-comparison-t","errorCode":null,"errorMessage":"worktree HEAD is not contained in the comparison target","messagePattern":"worktree HEAD is not contained in the comparison target","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/worktreeremove/policy.go","lineNumber":214,"sourceCode":"\t}\n\tif (facts.ManagedIgnore == IgnoreManaged) != (facts.ManagedIgnoreEntry != \"\") {\n\t\treturn Plan{}, fmt.Errorf(\"managed ignore cleanup identity is absent or invalid\")\n\t}\n\tif request.Mode != Force {\n\t\tif facts.Status != Clean {\n\t\t\treturn Plan{}, fmt.Errorf(\"worktree contains modified, untracked, or ignored files\")\n\t\t}\n\t\tif facts.Comparator != ComparatorAvailable && facts.Comparator != ComparatorMissing && facts.Comparator != ComparatorNotRequired {\n\t\t\treturn Plan{}, fmt.Errorf(\"worktree comparison target observation is absent or invalid\")\n\t\t}\n\t\tif facts.Comparator != ComparatorAvailable {\n\t\t\treturn Plan{}, fmt.Errorf(\"cannot verify unpushed commits: no comparison target is available\")\n\t\t}\n\t\tif facts.Containment != Contained && facts.Containment != NotContained && facts.Containment != ContainmentNotRequired {\n\t\t\treturn Plan{}, fmt.Errorf(\"worktree containment observation is absent or invalid\")\n\t\t}\n\t\tif facts.Containment != Contained {\n\t\t\treturn Plan{}, fmt.Errorf(\"worktree HEAD is not contained in the comparison target\")\n\t\t}\n\t} else if facts.Comparator != ComparatorNotRequired || facts.Containment != ContainmentNotRequired {\n\t\treturn Plan{}, fmt.Errorf(\"worktree force-mode comparison observations are inconsistent\")\n\t}\n\tplan := Plan{approved: true, mode: request.Mode, targetPath: facts.RegisteredPath}\n\tif facts.ManagedIgnore == IgnoreManaged {\n\t\tplan.managedIgnoreEntry = facts.ManagedIgnoreEntry\n\t}\n\treturn plan, nil\n}\n\n// InvariantState is the adapter's raw observation of one independently\n// revalidated invariant.\ntype InvariantState uint8\n\nconst (\n\t// InvariantUnknown means the adapter could not complete the observation.\n\tInvariantUnknown InvariantState = iota","sourceCodeStart":196,"sourceCodeEnd":232,"githubUrl":"https://github.com/gastownhall/beads/blob/71377f276968b452ee607177637970a4ff888584/internal/worktreeremove/policy.go#L196-L232","documentation":"Prepare rejects the request because mode is Normal and facts.Containment is NotContained: the worktree HEAD is not contained in the comparison target, meaning there are commits on the worktree branch that have not been pushed/merged. Normal-mode removal refuses to orphan those commits.","triggerScenarios":"Calling Prepare with Mode: Normal while the worktree branch has commits not present in the upstream/comparison ref (Containment == NotContained).","commonSituations":"Work done locally that was never pushed or merged; a rebase that rewrote commits so the upstream no longer contains the old HEAD; a comparator pointing at a branch missing recent commits.","solutions":["Push the worktree branch (git push) so the comparator contains its HEAD, then retry","Merge/rebase the worktree commits into the target branch and push","Use Force mode only if orphaning the commits is intentional"],"exampleFix":"// before\nplan, err := worktreeremove.Prepare(req, facts) // Normal mode, Containment == NotContained\n// after\n// git push in the worktree, re-observe facts (Containment becomes Contained), then:\nplan, err := worktreeremove.Prepare(req, facts)","handlingStrategy":"validation","validationCode":"if req.Mode == worktreeremove.Normal && facts.Containment != worktreeremove.Contained {\n\treturn fmt.Errorf(\"worktree HEAD not pushed; push or use Force\")\n}","typeGuard":"func headPushed(c worktreeremove.Containment) bool {\n\treturn c == worktreeremove.Contained\n}","tryCatchPattern":"plan, err := worktreeremove.Prepare(req, facts)\nif err != nil && strings.Contains(err.Error(), \"not contained in the comparison target\") {\n\treturn fmt.Errorf(\"push/merge worktree commits or use Force deliberately: %w\", err)\n}","preventionTips":["Verify git status shows the branch up to date before removal","Rebase/push after history rewrites so the comparator contains HEAD","Gate Force-mode removal behind explicit human confirmation"],"tags":["worktree","git","unpushed-commits"],"backgroundTag":"unpushed-commits","analyzedSha":"71377f276968b452ee607177637970a4ff888584","analyzedAt":"2026-08-30T18:55:39.744Z","schemaVersion":2},"datasetVersion":"2026-08-30T23:17:21.991Z"}