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
- Re-run GetRepoContextForWorkspace (or bd init) to rebuild the context after confirming where the beads dir went
- Check whether the path was deleted/moved (`ls <reported path>`) and restore or re-create it with `bd init`
- In long-running processes, catch this error and invalidate the cache, then re-resolve the context before the next operation
- 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
- Call Validate() before each use in long-running processes (DMN-002 pattern)
- Avoid deleting/relocating .beads while daemons hold a context
- Keep beads dirs on stable, always-mounted storage
- Rebuild context after any repo move or unmount
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
- RepoRoot no longer exists: %s
- no .beads directory found
- failed to create .beads directory: %w
- failed to close interactions log: %w
- beads directory missing required files: %s
AI-assisted analysis of gastownhall/beads@71377f2769 (2026-08-30).
Data as JSON: /api/errors/3dc659e54a885499.
Report an issue: GitHub.