Skip to content

fix: clear stale spawn error when sandbox connects#540

Merged
ColeMurray merged 1 commit into
mainfrom
worktree-fix+stale-spawn-error
Apr 22, 2026
Merged

fix: clear stale spawn error when sandbox connects#540
ColeMurray merged 1 commit into
mainfrom
worktree-fix+stale-spawn-error

Conversation

@ColeMurray
Copy link
Copy Markdown
Owner

@ColeMurray ColeMurray commented Apr 22, 2026

Summary

  • Control plane: onSandboxConnected() now calls setLastSpawnError(null, null) to clear the stale error from the DB when a sandbox successfully connects, not just the in-memory spawning flag.
  • Web client: The subscribed message handler now only overrides sandboxStatus to "failed" when data.state.sandboxStatus is actually "failed", rather than unconditionally whenever spawnError is truthy.

These two bugs combined caused the UI to show "failed" even when a sandbox recovered from a transient Modal 524 error and was actively running.

Test plan

  • Control-plane unit tests pass (991 tests)
  • Web unit tests pass (185 tests)
  • TypeScript type-check passes for both packages
  • Verify in staging: trigger a session, observe that after sandbox connects, sandboxStatus shows "ready" even if a prior spawn attempt failed

Summary by CodeRabbit

Bug Fixes

  • Improved sandbox connection error state management — spawn errors are now properly cleared when sandboxes successfully reconnect.
  • Enhanced sandbox failure detection — sandbox status is now correctly marked as failed only when both spawn errors and failed status conditions are present, reducing false failure reports.

When a Modal 524 error occurred during spawn but the container actually
started, the UI would still show "failed" due to two bugs:

1. onSandboxConnected() only reset the in-memory spawning flag but did
   not clear last_spawn_error from the DB, so the stale error persisted
   even after sandbox_status moved to "ready".

2. The web client's subscribed handler unconditionally overrode
   sandboxStatus to "failed" whenever spawnError was truthy, ignoring
   the authoritative sandboxStatus from the server.

Now onSandboxConnected() clears the spawn error, and the client only
applies the spawnError override when sandboxStatus is actually "failed".
@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Apr 22, 2026

📝 Walkthrough

Walkthrough

These changes refine spawn error state management across the sandbox lifecycle. The control-plane manager now clears persistent spawn error records when sandbox connection succeeds, while the web hook uses more precise conditional logic to report failed status.

Changes

Cohort / File(s) Summary
Spawn error cleanup on connection
packages/control-plane/src/sandbox/lifecycle/manager.ts
onSandboxConnected() now clears stored spawn error via setLastSpawnError(null, null) in addition to resetting in-memory spawning flag.
Session socket status refinement
packages/web/src/hooks/use-session-socket.ts
subscribed message handler now requires both data.spawnError presence and data.state?.sandboxStatus === "failed" before marking sandbox as failed, rather than checking error existence alone.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~8 minutes

Suggested reviewers

  • open-inspect

Poem

🐰 Errors cleared when sockets shine bright,
States align in logic just right,
Spawn and fail now sing in tune,
Sandbox connects—the clearing's soon! ✨

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. 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 accurately summarizes the main change: clearing stale spawn errors when a sandbox successfully connects, which is the primary fix across both files.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch worktree-fix+stale-spawn-error

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

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

@github-actions
Copy link
Copy Markdown

Terraform Validation Results

Step Status
Format
Init
Validate

Note: Terraform plan was skipped because secrets are not configured. This is expected for external contributors. See docs/GETTING_STARTED.md for setup instructions.

Pushed by: @ColeMurray, Action: pull_request

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

🧹 Nitpick comments (1)
packages/web/src/hooks/use-session-socket.ts (1)

313-316: Redundant setSessionState inside the guarded branch.

Now that the override only fires when data.state?.sandboxStatus === "failed", the setSessionState call on line 315 is a no-op: sessionState was already initialized from data.state at lines 287‑292 with that same sandboxStatus: "failed". You can drop the state update and keep just the console.error, or remove the branch entirely and rely on the generic state hydration above. Functionally correct either way — flagging as a minor cleanup.

♻️ Suggested simplification
-          if (data.spawnError && data.state?.sandboxStatus === "failed") {
-            console.error("Sandbox spawn error:", data.spawnError);
-            setSessionState((prev) => (prev ? { ...prev, sandboxStatus: "failed" } : null));
-          }
+          if (data.spawnError) {
+            console.error("Sandbox spawn error:", data.spawnError);
+          }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/web/src/hooks/use-session-socket.ts` around lines 313 - 316, The
if-block that checks data.spawnError and data.state?.sandboxStatus === "failed"
contains a redundant setSessionState call because sessionState was already
initialized from data.state earlier; remove the setSessionState((prev) => (prev
? { ...prev, sandboxStatus: "failed" } : null)) call (or remove the entire if
branch and keep only the console.error for data.spawnError) in
use-session-socket.ts so you no longer perform a no-op state update; keep
references to data.spawnError and the console.error message to preserve logging.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In `@packages/web/src/hooks/use-session-socket.ts`:
- Around line 313-316: The if-block that checks data.spawnError and
data.state?.sandboxStatus === "failed" contains a redundant setSessionState call
because sessionState was already initialized from data.state earlier; remove the
setSessionState((prev) => (prev ? { ...prev, sandboxStatus: "failed" } : null))
call (or remove the entire if branch and keep only the console.error for
data.spawnError) in use-session-socket.ts so you no longer perform a no-op state
update; keep references to data.spawnError and the console.error message to
preserve logging.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: cb1b48e4-be87-4095-a11c-935d4e76a114

📥 Commits

Reviewing files that changed from the base of the PR and between 5f4dcbe and 5460ef7.

📒 Files selected for processing (2)
  • packages/control-plane/src/sandbox/lifecycle/manager.ts
  • packages/web/src/hooks/use-session-socket.ts

@ColeMurray ColeMurray merged commit 6f9ee21 into main Apr 22, 2026
18 checks passed
@ColeMurray ColeMurray deleted the worktree-fix+stale-spawn-error branch April 22, 2026 18:31
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.

1 participant