gastownhall/beads · error

managed ignore cleanup identity is absent or invalid

Error message

managed ignore cleanup identity is absent or invalid

What it means

Prepare rejects the request because ManagedIgnore and ManagedIgnoreEntry are inconsistent: IgnoreManaged is set without a non-empty entry, or an entry string is present while ManagedIgnore says IgnoreAbsent. The cleanup identity must pair with its observation so the plan can authorize exactly one ignore-file edit.

Source

Thrown at internal/worktreeremove/policy.go:198

	default:
		return Plan{}, fmt.Errorf("registered worktree target is absent or invalid")
	}
	if facts.Registration != Present || facts.RegisteredPath == "" ||
		facts.TargetDir != Present || facts.GitAdminDir != Present ||
		facts.GitMarker != Present || facts.Head != Present {
		return Plan{}, fmt.Errorf("registered worktree target is absent or invalid")
	}
	if facts.CommonDir != Matched {
		return Plan{}, fmt.Errorf("target common git directory does not match repository")
	}
	if facts.Status != Clean && facts.Status != Dirty {
		return Plan{}, fmt.Errorf("worktree cleanliness observation is absent or invalid")
	}
	if facts.ManagedIgnore != IgnoreAbsent && facts.ManagedIgnore != IgnoreManaged {
		return Plan{}, fmt.Errorf("managed ignore observation is absent or invalid")
	}
	if (facts.ManagedIgnore == IgnoreManaged) != (facts.ManagedIgnoreEntry != "") {
		return Plan{}, fmt.Errorf("managed ignore cleanup identity is absent or invalid")
	}
	if request.Mode != Force {
		if facts.Status != Clean {
			return Plan{}, fmt.Errorf("worktree contains modified, untracked, or ignored files")
		}
		if facts.Comparator != ComparatorAvailable && facts.Comparator != ComparatorMissing && facts.Comparator != ComparatorNotRequired {
			return Plan{}, fmt.Errorf("worktree comparison target observation is absent or invalid")
		}
		if facts.Comparator != ComparatorAvailable {
			return Plan{}, fmt.Errorf("cannot verify unpushed commits: no comparison target is available")
		}
		if facts.Containment != Contained && facts.Containment != NotContained && facts.Containment != ContainmentNotRequired {
			return Plan{}, fmt.Errorf("worktree containment observation is absent or invalid")
		}
		if facts.Containment != Contained {
			return Plan{}, fmt.Errorf("worktree HEAD is not contained in the comparison target")
		}
	} else if facts.Comparator != ComparatorNotRequired || facts.Containment != ContainmentNotRequired {

View on GitHub (pinned to 71377f2769)

Solutions

  1. Set ManagedIgnoreEntry to the exact ignore-file entry when ManagedIgnore is IgnoreManaged
  2. Use IgnoreAbsent with an empty ManagedIgnoreEntry when there is no managed entry
  3. Keep the pair set together from a single observation point in the adapter

Example fix

// before
facts.ManagedIgnore = worktreeremove.IgnoreManaged // entry not set
// after
facts.ManagedIgnore = worktreeremove.IgnoreManaged
facts.ManagedIgnoreEntry = "worktrees/foo/" // exact entry from ignore file
Defensive patterns

Strategy: validation

Validate before calling

if (facts.ManagedIgnore == worktreeremove.IgnoreManaged) != (facts.ManagedIgnoreEntry != "") {
	return fmt.Errorf("managed ignore entry/kind mismatch")
}

Type guard

func ignorePairConsistent(f worktreeremove.PrepareFacts) bool {
	return (f.ManagedIgnore == worktreeremove.IgnoreManaged) == (f.ManagedIgnoreEntry != "")
}

Try / catch

plan, err := worktreeremove.Prepare(req, facts)
if err != nil && strings.Contains(err.Error(), "managed ignore cleanup identity") {
	return fmt.Errorf("re-observe ignore entry and kind together: %w", err)
}

Prevention

When it happens

Trigger: Calling Prepare with ManagedIgnore: IgnoreManaged but empty ManagedIgnoreEntry, or a non-empty ManagedIgnoreEntry together with IgnoreAbsent.

Common situations: Adapters that record the entry string but forget to flip ManagedIgnore; tests that set only one half of the pair; refactors that renamed the entry field.

Related errors


AI-assisted analysis of gastownhall/beads@71377f2769 (2026-08-30). Data as JSON: /api/errors/192a31085dc7f0aa. Report an issue: GitHub.