Skip to content

fix(inference): surface real reason for a slow inference invocation probe - #11287

Open
yimoj wants to merge 2 commits into
mainfrom
fix/11162-inference-probe-error-detail
Open

fix(inference): surface real reason for a slow inference invocation probe#11287
yimoj wants to merge 2 commits into
mainfrom
fix/11162-inference-probe-error-detail

Conversation

@yimoj

@yimoj yimoj commented Sep 9, 2026

Copy link
Copy Markdown
Collaborator

Outcome

The sandbox inference invocation probe no longer reports a false "sandbox inference invocation probe was unavailable" when the route/backend/upstream are healthy but the endpoint is merely slow. Before: a healthy-but-slow endpoint was SIGTERM-killed by the outer status timeout and collapsed into a generic "unavailable" message while Phase, route reachability, and backend all read healthy. After: curl's request budget sits safely inside the outer timeout so a slow-but-healthy endpoint is served, and when the probe genuinely does fail it reports the real reason (timeout vs subprocess error vs curl exit).

Reason

curl ran with a fixed --max-time 90 while the readiness/status outer exec timeout was 30_000 ms. An endpoint responding in 30–90 s was killed by the outer timeout (ETIMEDOUT/SIGTERM) before curl returned. The transport returned null on that kill, and the probe collapsed any null into the generic "was unavailable" with httpStatus: null, discarding the real cause. A commenter confirmed a ~35 s endpoint response reproduces exactly this on the current release; the rebuild path used a longer outer timeout but curl's fixed --max-time 90 could still race it.

Related issues

Fixes #11162

Changes

  • src/lib/adapters/sandbox/command-transport.ts: added SandboxCommandTransportFailure and a single exported classifySandboxCommandTransportFailure that distinguishes a timeout (ETIMEDOUT/SIGTERM) from a subprocess error, and reports it through a new optional onTransportFailure callback on SandboxExecCommandOptions. Only the subprocess error code crosses the boundary (no captured output). The callback fires only when the final result is null (including after a failed local fallback), so existing callers that pass no callback are unaffected.
  • src/lib/actions/sandbox/inference-invocation-probe.ts: on a null transport result the probe now surfaces the real reason (timed out after Ns / subprocess failed (<code>)) instead of the generic message; a curl-level timeout (exit 28) is reported as an endpoint timeout and other curl exits as curl exit N. resolveInferenceInvocationMaxTimeSeconds derives curl --max-time from the outer exec timeout with a 5 s buffer so curl (clean exit 28) always finishes before the outer timeout can SIGTERM the subprocess — readiness 30 s → --max-time 25, rebuild 100 s → --max-time 95. A genuine timeout still fails; it is only reported accurately, never masked. The same timeoutMs threads through both the exec and Deep Agents Code (runOpenshell) probe paths and all four consumers (status, start, inference set-provider, rebuild preflight).
  • Tests: added unit coverage for timeout vs subprocess-error classification (exec and DCode paths), curl exit 28 vs other exits, the generic fallback when no reason is reported, and the --max-time < outer timeout alignment for both budgets.

New mechanism justification: the onTransportFailure callback is the minimal seam. executeSandboxExecCommand/executeSandboxExecCommandTransport return SandboxCommandResult | null to many callers; widening the return type would ripple across unrelated call sites, so an additive optional callback that only the probe consumes keeps transport semantics unchanged for everyone else. It is protected by the new command-transport and probe unit tests.

Verification

  • npx vitest run src/lib/actions/sandbox/inference-invocation-probe.test.ts src/lib/adapters/sandbox/command-transport.test.ts — 49 passed
  • npm run typecheck:cli — passed for the changed files (two pre-existing plugin-artifact errors unrelated to this diff)
  • Local Linux+GPU E2E through the real worktree CLI on host yimoj-colossus-dev, sandbox wt11162-repro (OpenClaw, local Ollama llama3.2:1b, OpenShell 0.0.106), inducing the endpoint-slower-than-outer-timeout condition via the production NEMOCLAW_SANDBOX_EXEC_TIMEOUT_MS override:
    • Before fix: node ./bin/nemoclaw.js wt11162-repro statusInference: unreachable ... sandbox inference invocation probe was unavailable, exit 1, while route reachability + Ollama backend + auth proxy healthy and Phase Ready (false failure reproduced).
    • After fix (genuine timeout): same command → ... probe timed out after 100ms., exit 1 — accurate reason, no masking.
    • After fix (healthy): node ./bin/nemoclaw.js wt11162-repro statusInference: healthy, exit 0.
  • npm test (broad suite) — 148 pre-existing failures in unrelated subsystems (onboarding Dockerfile patch, CI-failure classifier, blueprint runner, messaging QR, npm cache seed, docs generation, dashboard remote-bind). Every failing file fails identically on the clean base with this change stashed and rebuilt; no failing file imports the modified modules. The two modified files' tests pass fully.
  • No secrets, API keys, or credentials are in the diff. Surfaced probe detail is limited to a duration, a Node error code, or a curl exit code.

Signed-off-by: Yimo Jiang yimoj@nvidia.com

Summary by CodeRabbit

  • Bug Fixes
    • Improved inference request timeout handling so requests complete within the available sandbox execution window.
    • Added clearer reporting for transport failures, including timeouts, subprocess errors, curl failures, and HTTP errors.
    • Endpoint timeouts are now identified consistently instead of appearing as generic unavailable or status errors.
    • Improved handling of sandbox execution failures while preserving existing fallback behavior when available.

…robe

The sandbox inference invocation probe reported a generic "sandbox
inference invocation probe was unavailable" whenever the transport
returned null, which happens when the outer exec timeout SIGTERM-kills
the curl subprocess. Because curl used a fixed --max-time 90 while the
status readiness timeout was 30s, a healthy-but-slow endpoint (30-90s)
was killed by the outer timeout and misreported as unavailable, even
though route reachability, backend, and upstream all reported healthy
(#11162).

- command-transport: classify a null result as timeout (ETIMEDOUT /
  SIGTERM) vs subprocess error via a shared
  classifySandboxCommandTransportFailure and report it through an
  optional onTransportFailure callback. Only the error code crosses the
  boundary; no captured output leaks.
- inference-invocation-probe: surface the real reason instead of the
  generic message, report curl exit 28 as an endpoint timeout, and
  derive curl --max-time from the outer exec timeout with a 5s buffer so
  curl bounds the request (clean exit 28) before the outer timeout can
  kill it, for both the readiness (30s -> 25s) and rebuild (100s -> 95s)
  paths. A genuine timeout still fails, but is reported accurately.

Fixes #11162

Signed-off-by: Yimo Jiang <yimoj@nvidia.com>
@coderabbitai

coderabbitai Bot commented Sep 9, 2026

Copy link
Copy Markdown
Contributor

Review Change StackReview Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Enterprise

Run ID: acf5c5c0-fe7d-4903-a036-d5a21e87e29c

📥 Commits

Reviewing files that changed from the base of the PR and between 38b5e3c and 6a2f364.

📒 Files selected for processing (4)
  • src/lib/actions/sandbox/inference-invocation-probe.test.ts
  • src/lib/actions/sandbox/inference-invocation-probe.ts
  • src/lib/adapters/sandbox/command-transport.test.ts
  • src/lib/adapters/sandbox/command-transport.ts

Included review availability: Your plan provides up to 12 included reviews per hour; 11 remain after this review.


📝 Walkthrough

Walkthrough

The inference probe now budgets curl timeouts from the outer sandbox timeout and reports classified transport, HTTP, curl, and launcher failures. Sandbox command transport exposes callbacks for timeout and subprocess failures while retaining fallback behavior.

Changes

Inference probe reliability

Layer / File(s) Summary
Transport failure classification
src/lib/adapters/sandbox/command-transport.ts, src/lib/adapters/sandbox/command-transport.test.ts
OpenShell execution classifies timeout and subprocess failures. It reports failures through onTransportFailure when fallback is unavailable. Tests cover SIGTERM timeouts and ENOENT spawn errors.
Inference timeout and failure propagation
src/lib/actions/sandbox/inference-invocation-probe.ts
The probe derives curl timeouts with a five-second buffer, propagates timeout values through standard and DCODe invocation paths, and reports specific transport, HTTP, and curl failures.
Timeout and failure behavior validation
src/lib/actions/sandbox/inference-invocation-probe.test.ts
Tests cover curl timeout budgeting, transport-failure callbacks, curl exit codes, and DCODe launcher failures.

Priority: ➖ Normal

Estimated code review effort: 3 (Moderate) | ~20 minutes

Severity of issue fixed: Medium

Merge Risk: ⚪ Minimal · up to 95d25

Inference probes now reserve time for curl to return a specific result before the sandbox execution deadline, improving diagnostics for slow endpoints and transport failures without an identified merge-blocking risk.

Sequence Diagram(s)

sequenceDiagram
  participant InferenceProbe
  participant CommandTransport
  participant OpenShell
  participant CurlEndpoint
  InferenceProbe->>CommandTransport: execute timeout-aware inference command
  CommandTransport->>OpenShell: run sandbox subprocess
  OpenShell->>CurlEndpoint: send curl request
  CurlEndpoint-->>OpenShell: return HTTP response or curl failure
  OpenShell-->>CommandTransport: return result or transport outcome
  CommandTransport-->>InferenceProbe: report result or classified failure
Loading

Suggested reviewers: apurvvkumaria, jyaunches, ericksoa

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 36.36% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 11 functions across 4 files. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly identifies the primary change: surfacing the actual reason for slow inference invocation probe failures.
Linked Issues check ✅ Passed The changes address issue #11162 by classifying outer-command timeouts and subprocess failures, deriving curl timeouts from the outer timeout, propagating timeout values through both probe paths, and …
Out of Scope Changes check ✅ Passed The implementation and tests remain within scope for issue #11162. The added transport classification, timeout budgeting, fallback handling, and coverage directly support accurate inference probe resu…
✨ Finishing Touches 💡 2
📝 Generate docstrings 💡
  • Create stacked PR
  • Commit on current branch
🛠️ Fix failing CI checks 💡
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/11162-inference-probe-error-detail

Comment @coderabbitai help to get the list of available commands.

@github-code-quality

github-code-quality Bot commented Sep 9, 2026

Copy link
Copy Markdown
Contributor

Code Coverage Overview

Languages: TypeScript

TypeScript / code-coverage/plugin

The overall line coverage in commit 95d25e4 in the fix/11162-inference-... branch remains at 96%, unchanged from commit 38b5e3c in the main branch.

TypeScript / code-coverage/cli

The overall line coverage in commit 95d25e4 in the fix/11162-inference-... branch remains at 83%, unchanged from commit 38b5e3c in the main branch.

Show a line coverage summary of the most impacted files.
File main 38b5e3c fix/11162-inference-... 95d25e4 +/-
src/lib/inferen...ycle-adapter.ts 86% 77% -9%
src/lib/onboard...eate-journal.ts 87% 80% -7%
src/lib/onboard...ntime-marker.ts 71% 65% -6%
src/lib/onboard...u-patch-mode.ts 90% 88% -2%
src/lib/inference/health.ts 90% 89% -1%
src/lib/inferen...file/cleanup.ts 81% 82% +1%
src/lib/onboard...ce-lifecycle.ts 83% 84% +1%
src/lib/onboard...box-prebuild.ts 91% 94% +3%
src/lib/onboard...wn-authority.ts 91% 98% +7%
src/lib/onboard...dns-fallback.ts 65% 85% +20%

Updated September 09, 2026 12:17 UTC

Signed-off-by: Yimo Jiang <yimoj@nvidia.com>
@github-actions

github-actions Bot commented Sep 9, 2026

Copy link
Copy Markdown
Contributor

PR Review Advisor finished for commit 95d25e4. Include the Advisor findings in the complete PR feedback collection. Verify and group valid findings before repair.

All previous runs

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.

[Inference] Sandbox inference invocation probe reports false failure while route/backend/upstream all report healthy

1 participant