gastownhall/beads · error

RepoRoot no longer exists: %s

Error message

RepoRoot no longer exists: %s

What it means

RepoContext.Validate() re-checks that the cached RepoRoot still exists; if os.Stat reports it missing, this error is returned. Like the BeadsDir check, it lets long-running processes detect that the repository root was deleted or moved after the context was captured (DMN-002). A stale RepoRoot means all git-based operations of the cached context are invalid.

Source

Thrown at internal/beads/context.go:538

	return &RepoContext{
		BeadsDir:     beadsDir,
		RepoRoot:     repoRoot,
		CWDRepoRoot:  cwdRepoRoot,
		IsRedirected: false, // Workspace-specific context is never "redirected"
		IsWorktree:   isWorktree,
	}, nil
}

// Validate checks if the cached context is still valid.
//
// Returns an error if BeadsDir or RepoRoot no longer exist. This is useful
// for long-running processes that need to detect when context becomes stale (DMN-002).
func (rc *RepoContext) Validate() error {
	if _, err := os.Stat(rc.BeadsDir); os.IsNotExist(err) {
		return fmt.Errorf("BeadsDir no longer exists: %s", rc.BeadsDir)
	}
	if _, err := os.Stat(rc.RepoRoot); os.IsNotExist(err) {
		return fmt.Errorf("RepoRoot no longer exists: %s", rc.RepoRoot)
	}
	return nil
}

// GitOutput runs a git command in the beads repository and returns its output.
//
// This is a convenience wrapper around GitCmd that captures stdout.
// Returns an error if the command fails or produces no output.
//
// Pattern:
//
//	output, err := rc.GitOutput(ctx, "config", "--get", "beads.role")
//	if err != nil {
//	    // Config key not set or git error
//	}
func (rc *RepoContext) GitOutput(ctx context.Context, args ...string) (string, error) {
	cmd := rc.GitCmd(ctx, args...)
	output, err := cmd.Output()

View on GitHub (pinned to 71377f2769)

Solutions

  1. Re-resolve the context from the new repo location (GetRepoContextForWorkspace at the moved path)
  2. Restore the repository (re-clone or re-mount) at the original path if other tooling depends on it
  3. In long-running processes, treat this error as 'rebuild context' and refresh the cached RepoContext
  4. Check for typos in any configured repo path if the path never existed

Example fix

// before
if err := ctx.Validate(); err == nil { use(ctx) }
// after
if err := ctx.Validate(); err != nil {
    ctx, err = beads.GetRepoContextForWorkspace(newRepoPath)
}
Defensive patterns

Strategy: validation

Validate before calling

if _, err := os.Stat(cached.RepoRoot); os.IsNotExist(err) {
    cached, err = beads.GetRepoContextForWorkspace(newRepoPath)
}

Try / catch

if err := rc.Validate(); err != nil {
    if strings.Contains(err.Error(), "RepoRoot no longer exists") {
        rc, err = beads.GetRepoContextForWorkspace(locateRepo())
    }
}

Prevention

When it happens

Trigger: Calling rc.Validate() on a RepoContext whose rc.RepoRoot path no longer exists — the repo was deleted, moved, or its mount disappeared after the context was built.

Common situations: Working in a repo checked out in /tmp that was cleaned up; a repo directory renamed while a daemon holds the context; a network checkout that went offline; CI workspaces deleted between steps while a process still caches the context.

Related errors


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