gastownhall/beads · error
no .beads directory found
Error message
no .beads directory found
What it means
buildRepoContext resolves the repository context once per process via sync.Once; if FindBeadsDir() (which respects BEADS_DIR) cannot locate a .beads directory, it returns this error. GetRepoContext then returns it on every subsequent call because the failure is cached for the process lifetime. It means bd cannot find any beads workspace — from the CWD upward, via git root, or via BEADS_DIR.
Source
Thrown at internal/beads/context.go:108
// 1. CWD doesn't change during command execution
// 2. BEADS_DIR doesn't change during command execution
// 3. Repeated filesystem access would be wasteful
//
// Returns an error if no .beads directory can be found.
func GetRepoContext() (*RepoContext, error) {
repoCtxOnce.Do(func() {
repoCtx, repoCtxErr = buildRepoContext()
})
return repoCtx, repoCtxErr
}
// buildRepoContext constructs the RepoContext by resolving all paths.
// This is called once per process via sync.Once.
func buildRepoContext() (*RepoContext, error) {
// 1. Find .beads directory (respects BEADS_DIR env var)
beadsDir := FindBeadsDir()
if beadsDir == "" {
return nil, fmt.Errorf("no .beads directory found")
}
// 2. Security: Validate path boundary (SEC-003)
if !isPathInSafeBoundary(beadsDir) {
return nil, fmt.Errorf("BEADS_DIR points to unsafe location: %s", beadsDir)
}
// 3. Check for redirect file in the local repo
redirectInfo := GetRedirectInfo()
// 4. Determine RepoRoot based on external/redirect status
var repoRoot string
isExternal := redirectInfo.IsRedirected
if !isExternal {
if external, err := isExternalBeadsDir(beadsDir); err == nil {
isExternal = external
}
}View on GitHub (pinned to 71377f2769)
Solutions
- Run `bd init` (or `git init` + `bd init`) in the repository root to create .beads/.
- cd into the repository that contains the .beads directory before running bd.
- Fix or unset BEADS_DIR — verify the path exists and contains a .beads dir.
- Check whether .beads/ was deleted or is missing after a fresh clone; restore or re-init it.
- Since the failure is cached via sync.Once, restart the process after fixing the environment.
Example fix
// before
rc, err := beads.GetRepoContext() // "no .beads directory found" in fresh clone
// after
if _, statErr := os.Stat(".beads"); os.IsNotExist(statErr) {
return fmt.Errorf("run `bd init` first: %w", err)
}
rc, err := beads.GetRepoContext() Defensive patterns
Strategy: validation
Validate before calling
if os.Getenv("BEADS_DIR") == "" {
if _, err := os.Stat(".beads"); os.IsNotExist(err) {
return fmt.Errorf("no .beads directory here; run `bd init`")
}
} Try / catch
if _, err := beads.GetRepoContext(); err != nil {
if strings.Contains(err.Error(), "no .beads directory found") {
return fmt.Errorf("run `bd init` in your repository first: %w", err)
}
return err
} Prevention
- Run `bd init` in every repo before using bd commands.
- cd into the repository root (or a subdirectory of it) before invoking bd.
- Verify BEADS_DIR points to an existing .beads directory.
- Restart processes after creating .beads — the lookup result is cached per process.
When it happens
Trigger: Running bd commands outside any repository that contains .beads/; a repo where .beads/ was never initialized (no `bd init`); BEADS_DIR set to a nonexistent or misspelled path; running from a directory outside the repo subtree with no discovery path to a .beads dir.
Common situations: Cloning a repo whose .beads/ directory was gitignored and never created; running bd in $HOME or a scratch directory; typos in BEADS_DIR; CI jobs checking out only a subdirectory.
Related errors
AI-assisted analysis of gastownhall/beads@71377f2769 (2026-08-30).
Data as JSON: /api/errors/57c55dd6f7888959.
Report an issue: GitHub.