Skip to content

Surface error cause chain in CLI error messages - #1190

Merged
ymichael merged 2 commits into
get-bb:mainfrom
sholub-dev:unwrap-error-cause-chain-in-cli
Aug 10, 2026
Merged

Surface error cause chain in CLI error messages#1190
ymichael merged 2 commits into
get-bb:mainfrom
sholub-dev:unwrap-error-cause-chain-in-cli

Conversation

@sholub-dev

@sholub-dev sholub-dev commented Aug 8, 2026

Copy link
Copy Markdown
Contributor

Summary

Fixes #1189. Node's fetch rejects with a generic TypeError: fetch failed and keeps the actionable socket error (for example, connect EPERM 127.0.0.1:38886) under .cause. For multi-address connections such as localhost, that cause can be an AggregateError whose .errors contain the per-address failures.

The CLI's getErrorMessage previously read only the outer .message, so distinct failures all printed the same uninformative Error: fetch failed.

Walk the error graph when formatting CLI errors:

  • follow ordinary .cause chains;
  • include every nested AggregateError.errors entry;
  • skip empty wrapper messages; and
  • stop safely on cyclic graphs.

A sandbox-blocked connection now prints the underlying EPERM detail, including when it is one attempt in a multi-address connection. The existing ECONNREFUSED mapping to "Cannot connect to BB server" is unchanged.

Verification

  • pnpm exec turbo run typecheck --filter=@bb/cli --force
  • pnpm exec turbo run test --filter=@bb/cli --force
  • pnpm exec turbo run build --filter=@bb/cli --force
  • Prettier check for the changed files

ymichael added a commit that referenced this pull request Aug 10, 2026
…1218)

Fixes #1216.

## Summary

The unknown-command plugin probe caught its fetch error with a bare
`catch`, so every failure — ECONNREFUSED, EPERM from a sandboxed shell,
a timeout — printed the same "bb isn't running — open the bb app, then
re-run this command." That message asserts a fact the code had no
evidence for, and agents act on it: they declare a healthy bb dead and
abandon queued work.

The probe now keeps the thrown error, and `describeUnreachableServer`
derives the message from the cause chain:

- `ECONNREFUSED` — the only evidence bb is actually down — keeps the
existing guidance, now naming the address: `bb is not running at <url> —
open the bb app, then re-run this command.`
- `EPERM`/`EACCES`: `Cannot reach bb at <url>: EPERM — the connection
was blocked. bb may still be running; check sandbox or firewall rules
for this shell.`
- Timeout: `bb did not respond at <url> within 2000ms — it may be busy
or unreachable.`
- Anything else prints the unwrapped cause chain.

The related built-in-command formatter fix (`.cause` discarded by
`getErrorMessage`) is #1190; this covers the probe path, which discards
the error before any formatter runs.

---------

Co-authored-by: Michael Yong <wrong92@gmail.com>
@ymichael
ymichael force-pushed the unwrap-error-cause-chain-in-cli branch from e8464b0 to 32cfa97 Compare August 10, 2026 23:02
@ymichael
ymichael merged commit 34c8fa0 into get-bb:main Aug 10, 2026
9 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

bb CLI: "Error: fetch failed" discards the error cause, making an unreachable backend indistinguishable from a dead one

2 participants