Skip to content

fix(dep): tolerate unresolved IDs in batch dep list#3620

Merged
harry-miller-trimble merged 1 commit into
gastownhall:mainfrom
pae23:fix/dep-list-batch-tolerate-unresolved
May 5, 2026
Merged

fix(dep): tolerate unresolved IDs in batch dep list#3620
harry-miller-trimble merged 1 commit into
gastownhall:mainfrom
pae23:fix/dep-list-batch-tolerate-unresolved

Conversation

@pae23

@pae23 pae23 commented May 1, 2026

Copy link
Copy Markdown
Contributor

Summary

When bd dep list is invoked with multiple IDs (batch mode), a single unresolvable ID currently aborts the entire call with exit 1. This makes bd dep list unusable as a transport primitive for callers that fetch deps for a snapshot of IDs from another store, since their snapshot may transiently include IDs the resolver cannot find.

Concrete consumer

gastownhall/gascity#1560 — gascity's CachingStore reconcile loop calls bd dep list <all-bead-ids> --json every 30–60 s. Ephemeral *-wisp-* patrol-molecule beads are visible to bd list but not resolvable by bd show / bd dep list, so the supervisor's batch fails wholesale on every cycle, cascading into stale-cache session-lifecycle bugs.

Behavior change

Mode Before After
Single arg (bd dep list X) Fatal exit on resolution failure UNCHANGED — fatal exit (matches bd show semantics)
Batch (bd dep list X Y Z) One bad ID kills the whole batch Unresolvable IDs skipped with stderr warning (warning: resolving X: ... (skipped)); resolvable IDs continue
Batch + --json Exit 1, JSON error envelope on stdout Valid JSON array on stdout (only resolvable IDs); empty [] if none resolve

Why batch tolerance

bd dep list in batch mode is a transport primitive — callers want "deps for the IDs I have right now". They cannot pre-validate every ID without a round-trip per ID, defeating the purpose of batch. ZFC: the transport mechanically degrades on bad input instead of forcing the caller to reason about which IDs might fail.

Single-arg behavior is intentionally preserved as a backward-compat decision: existing scripts that rely on bd dep list X failing loudly when X is missing keep working.

Test plan

  • go build ./cmd/bd — builds clean
  • go test ./cmd/bd -run Dep — passes (1.811 s)
  • Smoke test:
    bd dep list <good-id> ga-FAKE --json
    → exit 0, stderr "warning: resolving ga-FAKE: ... (skipped)", stdout "[]"
    bd dep list ga-FAKE --json
    → exit 1, JSON error (unchanged single-arg behavior)
    

Adjacent issue (not addressed here)

Beads also has a separate consistency bug: *-wisp-* molecule beads appear in bd list but are unresolvable by bd show, bd dep list, AND bd list --all excludes them entirely. That root cause is worth fixing too (consistency of list/show/--all/dep), but this PR is the smaller, surgical change that unblocks the gascity reconcile loop today regardless of how the wisp inconsistency is resolved.

🤖 Generated with Claude Code


View in Codesmith
Need help on this PR? Tag @codesmith with what you need.

  • Let Codesmith autofix CI failures and bot reviews

When `bd dep list` is invoked with multiple IDs (batch mode), a single
unresolvable ID currently aborts the entire call with exit 1. This makes
the command unusable as a transport primitive for callers that want to
fetch deps for a snapshot of IDs from another store, since their snapshot
may transiently include IDs that the resolver cannot find.

Concrete consumer: gascity's CachingStore reconcile loop calls
`bd dep list <all-bead-ids> --json` every 30-60s. Ephemeral
`*-wisp-*` patrol-molecule beads are visible to `bd list` but not
resolvable by `bd show` / `bd dep list` (separate consistency bug
to track), so the supervisor's batch fails wholesale on every cycle.
See gastownhall/gascity#1560.

Behavior change

- Single-arg mode (len(args) == 1): UNCHANGED. Fatal exit on
  resolution failure, matching `bd show` semantics.
- Batch mode (len(args) > 1): unresolvable IDs are skipped with
  a stderr warning ("warning: resolving X: ... (skipped)"); the
  command continues with the remaining resolvable IDs and still
  produces a valid JSON array on stdout. If NO IDs resolve, an
  empty `[]` is emitted under --json (exit 0) so callers parse
  cleanly.

This keeps `bd` ZFC-compliant for its caller: the transport
mechanically degrades on bad input instead of forcing the caller
to pre-validate every ID.
@codecov-commenter

codecov-commenter commented May 1, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 0% with 13 lines in your changes missing coverage. Please review.
✅ All tests successful. No failed tests found.

Files with missing lines Patch % Lines
cmd/bd/dep.go 0.00% 13 Missing ⚠️

📢 Thoughts on this report? Let us know!

@harry-miller-trimble harry-miller-trimble left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM — graceful degradation in batch mode without breaking single-ID callers. Clean implementation.

@harry-miller-trimble harry-miller-trimble merged commit ccfb97f into gastownhall:main May 5, 2026
39 checks passed
@maphew maphew added the triaged Issue has been reviewed and responded to label May 6, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

triaged Issue has been reviewed and responded to

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants