gastownhall/beads · error

BeadsDir no longer exists: %s

Error message

BeadsDir no longer exists: %s

What it means

RepoContext.Validate() re-checks that the cached BeadsDir still exists on disk; if os.Stat reports it missing, the cached context is stale and this error is returned. It exists for long-running processes (per DMN-002) that must detect when the beads directory was deleted or moved after the context was built. The caller should rebuild the context.

Source

Thrown at internal/beads/context.go:535

	// 6. Get CWD's repo root (same as workspace in this case)
	cwdRepoRoot := git.GetRepoRoot()

	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
//	}

View on GitHub (pinned to 71377f2769)

Solutions

  1. Re-run GetRepoContextForWorkspace (or bd init) to rebuild the context after confirming where the beads dir went
  2. Check whether the path was deleted/moved (`ls <reported path>`) and restore or re-create it with `bd init`
  3. In long-running processes, catch this error and invalidate the cache, then re-resolve the context before the next operation
  4. Verify mounts/volumes that host the beads directory are attached

Example fix

// before
cachedCtx.DoWork()
// after
if err := cachedCtx.Validate(); err != nil {
    cachedCtx, err = beads.GetRepoContextForWorkspace(cwd) // rebuild stale context
}
Defensive patterns

Strategy: validation

Validate before calling

if _, err := os.Stat(cached.BeadsDir); os.IsNotExist(err) {
    cached, err = beads.GetRepoContextForWorkspace(cwd) // rebuild
}

Try / catch

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

Prevention

When it happens

Trigger: Calling rc.Validate() on a RepoContext whose rc.BeadsDir path no longer exists — the .beads directory was deleted, renamed, or unmounted after the context was cached.

Common situations: A long-running daemon holding a RepoContext while the repo was deleted or moved; an unmounted network/external drive hosting the beads dir; a container restart with an ephemeral filesystem; tests deleting temp dirs while a cached context still points at them.

Related errors


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