fix(crabbox): retry cold metadata probes so a slow run --help does not block validation#102159
Conversation
…t block validation
The wrapper probes `crabbox --version` and `crabbox run --help` once each with a
snappy 5s timeout to enumerate providers before delegating. A cold Crabbox — the
first call right after a version bump, or one on a loaded machine — can exceed
that timeout while rendering `run --help` (52KB, emitted on stderr in 0.36) or
doing first-run init, and can emit nothing on that first call. When that happens
both guards fire and hard-exit the wrapper ("selected binary failed basic
--version/--help sanity checks" or "could not parse provider list from --help;
refusing to run"), which blocks ALL remote validation (`pnpm check:changed`,
remote `pnpm test` lanes) even though the binary is fine.
Retry each metadata probe once with a generous 20s timeout when the first attempt
is killed or returns empty. The warm path is unchanged (one ~instant probe); only
a slow/empty first probe pays for the retry, after which the sanity/provider-list
guards judge the recovered result. Add a regression test: a fake Crabbox whose
`run --help` is slower than the default probe timeout (and, like 0.36, writes help
to stderr) is now recovered by the retry instead of hard-failing.
|
Codex review: needs maintainer review before merge. Reviewed July 8, 2026, 7:49 AM ET / 11:49 UTC. Summary PR surface: Tests +44, Other +18. Total +62 across 2 files. Reproducibility: yes. at source level: current Review metrics: 1 noteworthy metric.
Stored data model Merge readiness Overall follows the weaker of proof and patch quality, so missing proof can cap an otherwise strong patch. Rank-up moves:
Risk before merge
Maintainer options:
Next step before merge
Maintainer decision needed
Security Review detailsBest possible solution: Land the bounded retry if maintainers accept the slower broken-binary failure path, while keeping provider validation and the focused regression coverage intact. Do we have a high-confidence way to reproduce the issue? Yes at source level: current Is this the best way to solve the issue? Yes. Retrying only unusable metadata probes preserves the safety guards and is narrower than raising the default timeout for every probe; the main tradeoff is the longer failed-binary path. AGENTS.md: found and applied where relevant. Codex review notes: model internal, reasoning high; reviewed against 58891c85b68b. Label changesLabel changes:
Label justifications:
Evidence reviewedPR surface: Tests +44, Other +18. Total +62 across 2 files. View PR surface stats
What I checked:
Likely related people:
What the crustacean ranks mean
Shiny media proof means a screenshot, video, or linked artifact directly shows the changed behavior. Runtime, network, CSP, and security claims still need visible diagnostics. How this review workflow works
|
…t block validation (openclaw#102159) The wrapper probes `crabbox --version` and `crabbox run --help` once each with a snappy 5s timeout to enumerate providers before delegating. A cold Crabbox — the first call right after a version bump, or one on a loaded machine — can exceed that timeout while rendering `run --help` (52KB, emitted on stderr in 0.36) or doing first-run init, and can emit nothing on that first call. When that happens both guards fire and hard-exit the wrapper ("selected binary failed basic --version/--help sanity checks" or "could not parse provider list from --help; refusing to run"), which blocks ALL remote validation (`pnpm check:changed`, remote `pnpm test` lanes) even though the binary is fine. Retry each metadata probe once with a generous 20s timeout when the first attempt is killed or returns empty. The warm path is unchanged (one ~instant probe); only a slow/empty first probe pays for the retry, after which the sanity/provider-list guards judge the recovered result. Add a regression test: a fake Crabbox whose `run --help` is slower than the default probe timeout (and, like 0.36, writes help to stderr) is now recovered by the retry instead of hard-failing.
…t block validation (openclaw#102159) The wrapper probes `crabbox --version` and `crabbox run --help` once each with a snappy 5s timeout to enumerate providers before delegating. A cold Crabbox — the first call right after a version bump, or one on a loaded machine — can exceed that timeout while rendering `run --help` (52KB, emitted on stderr in 0.36) or doing first-run init, and can emit nothing on that first call. When that happens both guards fire and hard-exit the wrapper ("selected binary failed basic --version/--help sanity checks" or "could not parse provider list from --help; refusing to run"), which blocks ALL remote validation (`pnpm check:changed`, remote `pnpm test` lanes) even though the binary is fine. Retry each metadata probe once with a generous 20s timeout when the first attempt is killed or returns empty. The warm path is unchanged (one ~instant probe); only a slow/empty first probe pays for the retry, after which the sanity/provider-list guards judge the recovered result. Add a regression test: a fake Crabbox whose `run --help` is slower than the default probe timeout (and, like 0.36, writes help to stderr) is now recovered by the retry instead of hard-failing.
What Problem This Solves
Resolves an issue where
scripts/crabbox-wrapper.mjshard-exits and blocks all remote validation —pnpm check:changed, remotepnpm testlanes,scripts/prgates — when thecrabboxbinary is cold (the first call right after a version bump, or one on a loaded machine), even though the binary is perfectly fine.At startup the wrapper probes
crabbox --versionandcrabbox run --helponce each, with a snappy 5s timeout, to enumerate the advertised providers before delegating. Crabbox 0.36 rendersrun --helpas ~52KB on stderr, and a cold binary can exceed 5s rendering it or doing first-run init (and can return nothing on that first call). When the probe is SIGKILLed or comes back empty, one of two guards fires and exits the wrapper with code 2:[crabbox] selected binary failed basic --version/--help sanity checks, or[crabbox] could not parse provider list from --help; refusing to run with --provider without validationOnce Crabbox is warm the same probe returns in ~70ms, so the failure is transient — but while it lasts, every remote gate is dead.
Why This Change Was Made
The probe was a single attempt with an aggressive timeout and no recovery. This adds one generous retry:
probeCrabboxMetadata()runs the probe with the default 5s timeout and, only if the result is unusable (killed by timeout, or empty), runs it once more with a 20s timeout. The warm path is unchanged (one ~instant probe); only a slow/empty first probe pays for the retry, after which the existing sanity and provider-list guards judge the recovered result — so a genuinely broken or truly-hung binary still fails, just not a merely-cold one.This is deliberately minimal and preserves the guards' safety intent (they still reject a binary that never responds or never advertises the selected provider). It does not touch provider selection, sandbox enforcement, or the delegated-sync flow.
User Impact
Maintainers and agents no longer see
pnpm check:changed/ remote test lanes spuriously die with "refusing to run" or "sanity checks failed" the first time they invoke Crabbox after an upgrade or on a busy machine. The wrapper waits out one cold probe and proceeds. No config or flags change; the warm-path latency is identical.Evidence
crabbox run --help(0.36.0) exits 0 in ~0.07s warm, writing 52KB to stderr and 0 to stdout; the wrapper's parser handles it fine (71 providers). The failures reproduced only when the first probe was killed/empty — i.e. cold — which the retry now covers.node scripts/crabbox-wrapper.mjs runitself. It parsed all 71 providers (providers=agent-sandbox,anthropic-sandbox-runtime,…,xcp-ng), warmed a Blacksmith Testbox, delegated-synced, and ran on it — proving the wrapper is usable again (Actions run).run-oxlinton the script clean,tsgo:core:testclean,check:no-conflict-markerspass, andtest/scripts/crabbox-wrapper.test.ts188 passed.run --helpis slower than the default probe timeout and (like 0.36) writes help to stderr is now recovered by the retry — the wrapper parses providers and exits 0 instead of hard-failing. The existing "times out hung sanity probes" test still asserts a genuinely wedged binary is rejected (its probe stays clamped below both the initial and retry timeouts).