gastownhall/beads · error

failed to inspect target repo %s: %w

Error message

failed to inspect target repo %s: %w

What it means

This wraps a non-NotFound os.Stat error encountered while checking <repo>/.beads/metadata.json during a dry-run parent lookup. Unlike the not-initialized case, here the filesystem itself failed — permission denied, path is not traversable, I/O error — so the store's initialization state cannot even be determined. The wrapped %w carries the exact OS error.

Source

Thrown at cmd/bd/create.go:990

			return nil, fmt.Errorf("failed to initialize remote cache: %w", err)
		}
		// The dry-run parent lookup only reads from this cached remote store.
		// Do not add writes here; dry-runs must not mutate cached remotes.
		store, err := cache.OpenStore(ctx, repoPath, newPreviewStoreFromConfig)
		if err != nil {
			return nil, fmt.Errorf("dry-run parent lookup requires an existing cached remote store for %s: %w", repoPath, err)
		}
		return store, nil
	}

	targetPath := routing.ExpandPath(repoPath)
	beadsDir := filepath.Join(targetPath, ".beads")
	metadataPath := filepath.Join(beadsDir, "metadata.json")
	if _, err := os.Stat(metadataPath); err != nil {
		if os.IsNotExist(err) {
			return nil, fmt.Errorf("target repo %s is not initialized; refusing to initialize it during dry-run", targetPath)
		}
		return nil, fmt.Errorf("failed to inspect target repo %s: %w", targetPath, err)
	}

	store, err := newPreviewStoreFromConfig(ctx, beadsDir)
	if err != nil {
		return nil, fmt.Errorf("failed to open target store for dry-run: %w", err)
	}
	return store, nil
}

// isAmbiguousRepoTarget reports whether an explicit --repo value is a
// bare/relative filesystem path (not absolute, not "~/"-prefixed). Such a
// value silently resolves against the current working directory (see
// routing.ExpandPath) rather than failing, so a misresolved value (e.g. a
// typo) previously wrote a bead into a brand-new, disconnected database
// instead of erroring (bd-8d3f).
func isAmbiguousRepoTarget(repoFlagChanged bool, repoOverride string) bool {
	return repoFlagChanged && !filepath.IsAbs(repoOverride) && !strings.HasPrefix(repoOverride, "~/")
}

View on GitHub (pinned to 71377f2769)

Solutions

  1. Fix filesystem permissions on the target repo and .beads/metadata.json (chmod/chown so the running user can stat/read them).
  2. Read the wrapped OS error (%w) to identify whether it is EACCES, ENOTDIR, etc., and address that specific cause.
  3. Verify no path component (repo dir or .beads) is actually a file or broken symlink; correct the layout.
  4. If running under a different account (CI, sudo, container), run the dry-run as a user with access to the checkout.
  5. Retry if the filesystem is network-mounted and the error indicates a transient I/O failure.

Example fix

// before: metadata.json unreadable (owned by root)
sudo bd init   # .beads now owned by root
bd create --dry-run "Task" --repo .   // failed to inspect target repo ...
// after: fix ownership/permissions, then retry
sudo chown -R $(whoami) .beads
bd create --dry-run "Task" --repo .
Defensive patterns

Strategy: validation

Validate before calling

// Probe readability of the target's beads metadata before invoking bd.
metadataPath := filepath.Join(routing.ExpandPath(repoPath), ".beads", "metadata.json")
if f, err := os.Open(metadataPath); err != nil {
    return fmt.Errorf("cannot read %s (check permissions/ownership): %w", metadataPath, err)
} else {
    f.Close()
}

Try / catch

store, err := openDryRunTargetStore(ctx, repoPath)
if err != nil {
    if errors.Is(err, os.ErrPermission) {
        fmt.Fprintf(os.Stderr, "Permission denied inspecting target repo. Fix ownership of %s/.beads.\n", repoPath)
        os.Exit(1)
    }
    return err
}

Prevention

When it happens

Trigger: bd create --dry-run --repo <path> where os.Stat on <path>/.beads/metadata.json fails with an error other than ENOENT: permission denied on the repo or .beads directory, metadata.json exists but is unreadable due to mode bits, a component of the path is a file not a directory, or an I/O/filesystem error occurs.

Common situations: Running bd as a different user (or in CI) without read access to the checkout; .beads owned by root after a sudo run; metadata.json with restrictive permissions; macOS/Windows path or symlink problems; network-mounted filesystems with transient I/O errors.

Related errors


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