fix(server): sandboxed Cursor threads keep working after a Full access thread - #13805
Conversation
…s thread The Cursor SDK caches whether local sandboxing works the first time any run starts, and only sandboxed runs point it at its cursorsandbox helper first. After one Full access run it caches "unsupported", and every later Supervised, Auto-accept edits, or Auto Cursor turn fails to start until the server restarts. Warm a bare sandboxed executor before the first unsandboxed agent opens so the SDK caches the real answer. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Thread transfer impact✅ Thread transfer remains within every enforced ceiling.
Baseline: unavailable · PR result: Scenario and decoded snapshot size10 historical turns, 5 command tools per turn, 878.9 KiB retained MCP result per historical turn, and a 1.05 MiB retained result in the measured turn.
Updated in place by a trusted workflow. PR artifacts are strictly validated and never executed. |
ApprovabilityVerdict: Approved at Macroscope's review found this PR approvable — This is a focused Cursor SDK bug fix that adds one best-effort, one-time sandbox capability warm-up before Full access agents and verifies the affected sequence with an opt-in live test. Existing policy values and unsupported-environment behavior remain unchanged, with only bounded first-use setup latency added. You can add or adjust custom eligibility rules. Learn more. |
4fafbbe
into
t3code/codex-turn-mapping
After one Full access Cursor thread runs, every later Supervised, Auto-accept edits, or Auto Cursor turn in that server fails with "Provider error: The provider could not start this turn" until the server restarts.
Evidence
Seen live on the V2 head with
gpt-5.4-nano. A Full access thread ran a turn. Then that thread was switched to Supervised, and separately a new Supervised thread was created. Both failed the next turn instantly. The server trace shows the cause:Sandboxing does work on that machine: the same server ran sandboxed turns fine when the first Cursor run after startup was sandboxed, and
cursorsandbox --preflight-onlyexits 0.Cause (upstream,
@cursor/sdk1.0.31, same code in 1.0.32)isSandboxSupported), then caches the answer.cursorsandboxhelper (configureSandboxPrereqs) before asking.Standalone repro against the SDK, with no T3 code involved. Each block is a fresh process with the same repo and model:
Fix
Before the first unsandboxed Cursor agent opens,
CursorAgentSdkRunner.openwarms a bare sandboxed executor once per process. It uses the SDK's publiccreateAgentPlatform().prewarmLocalWorkspace()with no setting sources and no MCP servers, then releases it right away. That configures the helper path, so the SDK caches the real answer. Sandboxed opens skip this because they configure the helper themselves.makeCursorAgentSdkRunner.Verification
CursorOrchestratorV2.live.test.ts: "runs a sandboxed thread after a full access thread in the same server". It runs a Full access thread, then a Supervised thread, through the real orchestrator and SDK in one process (T3_CURSOR_LIVE_ORCHESTRATOR=1,CURSOR_API_KEYset).expected [ 'failed' ] to deeply equal [ 'completed' ]for the Supervised thread. Ran twice, failed both times.vp test run src/orchestration-v2/Adapters/CursorAgentSdk.test.ts: 3 passed.vp test run src/orchestration-v2/testkit/OrchestratorReplayFixtures.integration.test.ts -t cursor: 10 passed.vp exec tsc --noEmit -p .inapps/server: noerror TSorwarning TS.vp lintandvp fmton the three touched files: clean.vp run knip:check: clean.sandbox-execpath), and the other live Cursor tests.Model: Claude Opus 5.5 (Claude Code)
🤖 Generated with Claude Code