gastownhall/beads · error
GetIssuesByIDs: %w
Error message
GetIssuesByIDs: %w
What it means
tryIncrementalExport fetches the issues it needs to upsert via store.GetIssuesByIDs. If the store lookup fails, the incremental path aborts with this wrapped error (and the caller, maybeAutoExport, falls back to a full export). It indicates a storage-layer failure, not a git/file problem.
Source
Thrown at cmd/bd/export_auto.go:1098
return 0, 0, nil, false, err
}
return issueCount, memoryCount, changed.Upserted, true, nil
}
if total > incrementalExportThreshold {
debug.Logf("auto-export: %d changes exceeds threshold %d; full export\n",
total, incrementalExportThreshold)
return 0, 0, nil, false, nil
}
// Fetch fresh data for upserted IDs (including anything carried over
// from last cycle) and apply the same template/infra/owner filters the
// full export uses.
var records map[string][]byte
droppedByFilter := make(map[string]bool)
if len(upsertIDs) > 0 {
issues, fetchErr := store.GetIssuesByIDs(ctx, upsertIDs)
if fetchErr != nil {
return 0, 0, nil, false, fmt.Errorf("GetIssuesByIDs: %w", fetchErr)
}
infraSet := store.GetInfraTypes(ctx)
// Owner-exclusion safety net, mirroring exportToFile's: without
// this, a config-excluded owner's issue that changes would leak
// into the git-committed JSONL via the incremental path even
// though the full-export path always excludes it (be-shbed).
ownerExcludes := buildOwnerExcludeSet(ctx, storeExportSource{}, nil)
filtered := make([]*types.Issue, 0, len(issues))
for _, iss := range issues {
// Record IDs that GetIssuesByIDs returned but we deliberately
// filtered out. Those DO need dropping from the export because
// the full-export path excludes them; leaving a stale record
// in place would diverge the two outputs.
if iss.IsTemplate {
droppedByFilter[iss.ID] = true
continue
}
if len(infraSet) > 0 && infraSet[string(iss.IssueType)] {View on GitHub (pinned to 71377f2769)
Solutions
- Retry the sync — maybeAutoExport falls back to a full export path which may succeed
- Check the local store health (`bd doctor`) for corruption or lock issues
- Close competing bd processes holding the database, then rerun `bd sync`
Example fix
// before // GetIssuesByIDs: database is locked // after bd doctor # verify store health bd sync # retries, falling back to full export if needed
Defensive patterns
Strategy: fallback
Validate before calling
// Check store responsiveness before incremental export
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
defer cancel()
if _, err := store.GetIssuesByIDs(ctx, []string{"smoke-test-id"}); err != nil && !errors.Is(err, ErrNotFound) {
fmt.Println("store unhealthy; prefer full export / bd doctor")
} Try / catch
count, _, _, _, err := tryIncrementalExport(...)
if err != nil && strings.Contains(err.Error(), "GetIssuesByIDs:") {
// Fall back to a full export, which rebuilds from a fresh store read
fullExport()
} Prevention
- Close competing bd processes before large sync operations
- Run `bd doctor` when store errors recur
- Avoid killing bd mid-write; let transactions finish
- Keep the storage driver and bd versions in sync
When it happens
Trigger: tryIncrementalExport calls store.GetIssuesByIDs(ctx, upsertIDs) for non-empty upsertIDs and the store returns an error — DB corruption, locked/closed database, driver failure.
Common situations: Dolt/database locked by another process; corrupted local store; storage driver errors; transient DB issues during rapid successive bd commands.
Related errors
AI-assisted analysis of gastownhall/beads@71377f2769 (2026-08-30).
Data as JSON: /api/errors/2412760851c71511.
Report an issue: GitHub.