Skip to content

fix(mount): classify transport rejections from the launch and daemon-start execs - #46

Merged
khaliqgant merged 1 commit into
mainfrom
fix/classify-mount-exec-rejections
Sep 1, 2026
Merged

fix(mount): classify transport rejections from the launch and daemon-start execs#46
khaliqgant merged 1 commit into
mainfrom
fix/classify-mount-exec-rejections

Conversation

@khaliqgant

@khaliqgant khaliqgant commented Sep 1, 2026

Copy link
Copy Markdown
Member

Refs #45.

The gap

startMount wraps its mkdir and status-probe execs so a rejected transport becomes a classified error, but leaves two unwrapped:

exec wrapped before on rejection
mkdir mount path yes classified
initial-sync launch no unclassifiable
status probe (poll loop) yes classified
daemon start no unclassifiable

Every throw in this function that embeds sandbox command output is one callers recognise by message prefix. So those two were the only paths that could produce an error matching no prefix at all — and callers bucket that as "invocation unknown" and drop the cause.

Why it matters right now

Cloud is failing 100% of JIT sandbox provisions on exactly that bucket. Measured 5/5 against production:

5/5  HTTP 503  phase: relayfile_mount_invocation_unknown
     mountElapsedMs 112143 / 131990 / 122960 / 133527 / 117733

~122s matches the ~120s Daytona proxy read timeout this file's own comment cites. The underlying error was unrecoverable from either the logs or the HTTP body, which is how this got chased as a Daytona provisioning-timeout problem for a day while Daytona was in fact creating the sandbox in 1.3 seconds.

Change

Wrap both in the same shape the two already-wrapped execs use, preserving the original as cause. A rejection now lands on Failed to launch relayfile initial sync: or Failed to start relayfile mount:, which callers already map to named phases (relayfile_mount_daemon_invoked_initial_sync_not_invoked and relayfile_mount_invoked_exited).

This makes the failure legible; it does not stop the exec from hanging. #45 stays open for the hang itself. Paired with AgentWorkforce/cloud#3244 (merged), the next occurrence will name which of the two died instead of returning an opaque phase — which is what the hang investigation needs to start from evidence rather than inference.

Tests

npm test819 pass, 0 fail. npm run typecheck clean.

Two new tests in orchestrator.start-mount.test.ts, mirroring the existing mkdir/status rejection tests: each asserts the classified message and that error.cause is the original transport error. The daemon-start one drives the full happy path first, since that exec is only reached after the initial sync reports a clean exit.

Red-check — reverting both wraps fails exactly the two new tests (# pass 817 # fail 2); restored, 819/0.

🤖 Generated with Claude Code

https://claude.ai/code/session_01AGB949mfHcP68whBJebzEM


Summary by cubic

Fixes startMount so transport rejections from the initial-sync launch and daemon-start execs are no longer unclassifiable. Previously only the mkdir and status-probe execs were wrapped, so failures in these two paths matched no caller-recognized message prefix, landed in the "invocation unknown" bucket, and lost the original cause.

Related to #45. Cloud is failing all JIT sandbox provisions on that unknown bucket after ~122s, which matches the ~120s Daytona proxy read timeout, and the underlying error was unrecoverable from logs or the HTTP body.

Written for commit 7765f12. Summary will update on new commits.

Review in cubic

…start execs

`startMount` wrapped its mkdir and status-probe execs so a rejected transport
becomes a classified error, but left the initial-sync launch and the daemon
start unwrapped. Every throw in this function that embeds sandbox output is one
callers recognise by message prefix, so those two were the only paths that could
produce an error matching no prefix at all — and callers bucket that as
"invocation unknown" and discard the cause.

That is not hypothetical. Cloud is currently failing 100% of JIT provisions
with `relayfile_mount_invocation_unknown` after ~122s, which matches Daytona's
~120s proxy read timeout, and the underlying error was unrecoverable from
either the logs or the HTTP body. See #45.

Wrap both in the same shape the two already-wrapped execs use, preserving the
original error as `cause`. A rejection now lands on
`Failed to launch relayfile initial sync:` or `Failed to start relayfile mount:`
respectively, which callers already map to named phases.

This makes the failure legible; it does not by itself stop the exec from
hanging. #45 stays open for the hang.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01AGB949mfHcP68whBJebzEM

Session-Id: 1fa09ce6-c8d4-4c4a-ad2b-0f1999cb237d
@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Sep 1, 2026

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review Completed 2026-09-01T13:05:27.003298Z 7765f12 PR opened
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@coderabbitai

coderabbitai Bot commented Sep 1, 2026

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Team

Run ID: 6618c9a3-b590-47a8-bdef-52768e8e4663

📥 Commits

Reviewing files that changed from the base of the PR and between d68a71b and 7765f12.

📒 Files selected for processing (2)
  • src/orchestrator.start-mount.test.ts
  • src/orchestrator.ts

Included review availability: Your plan provides up to 1 included review per hour; 0 remain after this review.


📝 Walkthrough

Walkthrough

startMount now adds context to initial-sync and mount-start failures. Each wrapped error preserves the original adapter error as cause. Tests cover both failure points and command execution order.

Changes

startMount error handling

Layer / File(s) Summary
Contextual error wrapping and validation
src/orchestrator.ts, src/orchestrator.start-mount.test.ts
startMount wraps initial-sync and mount-start failures with operation-specific messages and preserves the original errors as cause. Tests verify both classifications and expected command execution.

Estimated code review effort: 2 (Simple) | ~10 minutes

Merge Risk: ⚪ Minimal · up to 7765f

The change adds operation-specific context to existing mount execution failures without altering mount behavior or system boundaries. It is merge-ready after normal checks and review, with no actionable merge-blocking risk remaining.

Suggested reviewers: miyaontherelay, kjgbot

Poem

A rabbit hops where start scripts run
Errors now tell what went wrong
Their causes stay tucked safely near
Tests check the path from far to here
The relay mount begins with cheer

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly and concisely identifies the main change: classification of transport rejections from the launch and daemon-start executions.
Description check ✅ Passed The description directly explains the unwrapped execution paths, the new error classification, cause preservation, tests, and the scope limit regarding execution hangs.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check. Docstring coverage is scoped to functions touched by this diff. Analyzed 0 functions across 2…
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.
Full details: Docstring Coverage

Explanation

No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check. Docstring coverage is scoped to functions touched by this diff. Analyzed 0 functions across 2 files.

✨ 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 fix/classify-mount-exec-rejections

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.

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

No issues found across 2 files

Re-trigger cubic

@khaliqgant
khaliqgant merged commit 3899c81 into main Sep 1, 2026
4 checks passed
@khaliqgant
khaliqgant deleted the fix/classify-mount-exec-rejections branch September 1, 2026 13:11
khaliqgant added a commit that referenced this pull request Sep 1, 2026
Ships #46 — startMount now classifies transport rejections from the
initial-sync launch and daemon-start execs instead of letting them fall
through to the caller's unknown bucket.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01AGB949mfHcP68whBJebzEM

Session-Id: 1fa09ce6-c8d4-4c4a-ad2b-0f1999cb237d
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