gastownhall/beads · error
%w: %s
Error message
%w: %s
What it means
When `git add` exits non-zero, gitAddFile wraps the exec error with git's combined stdout/stderr output so the caller's warning shows the real reason (e.g. "paths are ignored", "Unable to create index.lock") instead of just an exit-status message. The %w preserves the original *exec.ExitError for errors.Is/As checks.
Source
Thrown at cmd/bd/export_auto.go:879
// .beads/issues.jsonl → pathspec looks under .beads/.beads/) if a caller
// ever passed a relative path here. Both current callers pass absolute
// paths, so this guards against a regression rather than fixing a live
// failure. See GH#4351.
// Keep cmd.Dir = parent so GH#3311 hook worktree staging still resolves
// the index path under the repo root (not bare "issues.jsonl" at root).
cmd := exec.CommandContext(ctx, "git", "add", "--", filepath.Base(path))
cmd.Dir = filepath.Dir(path)
cmd.Env = env
// Capture combined output so the caller's warning surfaces git's stderr
// (e.g. "paths are ignored", "Unable to create index.lock") instead of
// just the exit-status text.
out, err := cmd.CombinedOutput()
if ctx.Err() == context.DeadlineExceeded {
return fmt.Errorf("git add timed out after %s", gitAddTimeout)
}
if err != nil {
if trimmed := strings.TrimSpace(string(out)); trimmed != "" {
return fmt.Errorf("%w: %s", err, trimmed)
}
return err
}
return nil
}
func gitIndexLockPath(path string, env []string) (string, error) {
ctx, cancel := context.WithTimeout(context.Background(), gitAddTimeout)
defer cancel()
cmd := exec.CommandContext(ctx, "git", "rev-parse", "--git-dir")
cmd.Dir = filepath.Dir(path)
cmd.Env = env
out, err := cmd.CombinedOutput()
if ctx.Err() == context.DeadlineExceeded {
return "", fmt.Errorf("git rev-parse timed out after %s", gitAddTimeout)
}
if err != nil {
if trimmed := strings.TrimSpace(string(out)); trimmed != "" {View on GitHub (pinned to 71377f2769)
Solutions
- Read the appended git output in the error to see the exact git failure and address it
- If the path is ignored, adjust .gitignore so .beads/issues.jsonl is tracked (or use explicit `git add -f` policy)
- Remove a stale .git/index.lock if output says Unable to create index.lock
- If the file is missing, rerun `bd sync`/export to regenerate it
Example fix
// before // exit status 1: The following paths are ignored by one of your .gitignore files: .beads/issues.jsonl // after # .gitignore !.beads/issues.jsonl bd sync
Defensive patterns
Strategy: try-catch
Validate before calling
// Ensure the export path is not gitignored before relying on auto-stage
out, err := exec.Command("git", "check-ignore", ".beads/issues.jsonl").Output()
if err == nil && len(out) > 0 {
fmt.Println("warning: issues.jsonl is gitignored; git add will fail")
} Type guard
func isExitErrorWithOutput(err error) (*exec.ExitError, bool) {
var ee *exec.ExitError
return ee, errors.As(err, &ee)
} Try / catch
var ee *exec.ExitError
if err := autoExport(); err != nil {
if errors.As(err, &ee) && strings.Contains(err.Error(), "ignored") {
// Fix .gitignore so .beads/issues.jsonl is tracked, then retry
} else if errors.As(err, &ee) && strings.Contains(err.Error(), "index.lock") {
removeStaleLockAndRetry()
}
} Prevention
- Keep !.beads/issues.jsonl exceptions in .gitignore templates
- Read the git stderr appended to the error before guessing at fixes
- Unwrap with errors.As(*exec.ExitError) to branch on git failures programmatically
- Validate hook environments don't break git paths
When it happens
Trigger: gitAddFile's cmd.CombinedOutput() returns err != nil (non-zero exit from git add) with non-empty output; the exit error is wrapped as "%w: %s" with trimmed output appended.
Common situations: The JSONL path is gitignored so `git add` refuses; index.lock contention producing "Unable to create index.lock"; bad path (file deleted between export and staging); git version/config issues in hooks.
Related errors
- auto-export: git add failed: %w
- git index is locked at %s; skipping auto-stage
- failed to check git index lock %s: %w
- git add timed out after %s
- %w: %s
AI-assisted analysis of gastownhall/beads@71377f2769 (2026-08-30).
Data as JSON: /api/errors/0bfcbe6173645bc6.
Report an issue: GitHub.