gastownhall/beads · error

managed ignore observation is absent or invalid

Error message

managed ignore observation is absent or invalid

What it means

Prepare rejects the request because facts.ManagedIgnore is neither IgnoreAbsent nor IgnoreManaged. The observation of whether this worktree has a beads/git-managed ignore entry is missing or invalid, so the library cannot decide whether to schedule ignore-file cleanup.

Source

Thrown at internal/worktreeremove/policy.go:195

	case CurrentWorktree:
		return Plan{}, fmt.Errorf("cannot remove the worktree containing the running command")
	case RegisteredTarget:
	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 {

View on GitHub (pinned to 71377f2769)

Solutions

  1. Set facts.ManagedIgnore to IgnoreManaged or IgnoreAbsent based on inspecting the managed ignore file
  2. Fix the adapter so it always assigns a defined IgnoreKind even when the file is unreadable (use IgnoreAbsent only if truly absent)
  3. In tests, add ManagedIgnore: worktreeremove.IgnoreAbsent

Example fix

// before
facts.ManagedIgnore = 0 // zero value, invalid
// after
facts.ManagedIgnore = worktreeremove.IgnoreAbsent // or IgnoreManaged per observation
Defensive patterns

Strategy: validation

Validate before calling

if facts.ManagedIgnore != worktreeremove.IgnoreAbsent && facts.ManagedIgnore != worktreeremove.IgnoreManaged {
	return fmt.Errorf("managed-ignore state not observed")
}

Type guard

func ignoreObserved(k worktreeremove.IgnoreKind) bool {
	return k == worktreeremove.IgnoreAbsent || k == worktreeremove.IgnoreManaged
}

Try / catch

plan, err := worktreeremove.Prepare(req, facts)
if err != nil && strings.Contains(err.Error(), "managed ignore observation is absent") {
	return fmt.Errorf("inspect the managed ignore file before retrying: %w", err)
}

Prevention

When it happens

Trigger: Calling Prepare with a zero-value or out-of-range ManagedIgnore value, typically from an adapter that never inspected the managed ignore file.

Common situations: Custom adapters not reading the managed ignore file; tests constructing PrepareFacts without ManagedIgnore; enum drift after new IgnoreKind values were added.

Related errors


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