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

  1. Run `bd init` (or `git init` + `bd init`) in the repository root to create .beads/.
  2. cd into the repository that contains the .beads directory before running bd.
  3. Fix or unset BEADS_DIR — verify the path exists and contains a .beads dir.
  4. Check whether .beads/ was deleted or is missing after a fresh clone; restore or re-init it.
  5. 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

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.