Skip to content

fix(cursor): shell commands that exit non-zero are recorded as failed - #29785

Open
saphid wants to merge 1 commit into
pingdotgg:mainfrom
saphid:fix/cursor-hunt
Open

saphid wants to merge 1 commit into
pingdotgg:mainfrom
saphid:fix/cursor-hunt

Conversation

@saphid

@saphid saphid commented Nov 3, 2026

Copy link
Copy Markdown
Contributor

Problem

When a Cursor agent runs a shell command that exits non-zero, such as a failing test run, T3 Code stores the command and its tool node as completed. The Cursor SDK (1.2.0) reports both a successful and a failed shell result as status: "success" and only carries the failure in exitCode. cursorToolFailed looked only at status: "error" and MCP isError.

The web and mobile work log already check exitCode first, so the icon is usually right. But the thread timeline returned by t3_thread_read (OrchestratorMcpService.timelineItem) gives each item's stored status, and its command text ($ cmd plus output) has no exit code. An agent reading a delegated Cursor thread sees the failed run as completed. Codex, Claude, Grok and ACP all store failed for the same command.

Change

cursorToolFailed now treats a shell result with a non-zero exitCode as failed, the same check Grok uses (xaiAcpExtension.ts: non-zero exitCode -> failed). Both the execution node and the command_execution turn item take their status from this function. Other tool types are unaffected. Nested subagent shell results already map a raw failure to an error.

Scope and approval

Very small, focused fix for an obvious bug, so no prior issue: 4 non-test lines in one function, matching what the other adapters already do, plus one row in an existing test.

Overlap search: nothing open touches this function or Cursor shell exit status. #21448 (merged) fixed unfinished Cursor tools reported as successful, which is a different path. #26592 (merged) covered subagent ls/lint/MCP results. #29748 is Cursor text-generation error detail.

Verification

  • Red on main: the extended projects Cursor tasks and unfinished tools case failed in all 5 rows with - "shell-exit-1": "failed" / + "shell-exit-1": "completed".
  • Green: vp test run src/server/adapter.test.ts in packages/provider-cursor gives 21/21 passed. apps/server CursorReplayFixtures.integration.test.ts gives 11/11 passed.
  • vp run check:changed: format, lint, knip, typecheck (10 packages) and tests all pass.
  • I confirmed the SDK mapping in @cursor/sdk/dist/esm/336.js (case "success": case "failure": return {status: "success", value: {exitCode, ...}}). I didn't run a live Cursor turn.

Reviewed with sol-loop: 1 round with GPT-6.1 Sol on high. Sol verdict: approved.

Created with Claude Opus 5.5 in Claude Code (T3 Code).

🤖 Generated with Claude Code

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@github-actions github-actions Bot added vouch:trusted PR author is trusted by repo permissions or the VOUCHED list. size:XS 0-9 changed lines (additions + deletions). labels Nov 3, 2026
@macroscopeapp

macroscopeapp Bot commented Nov 3, 2026

Copy link
Copy Markdown
Contributor

Approvability

Verdict: Approved at 4f07a45

Macroscope's review found this PR approvable — Cursor shell commands that exit nonzero will now be recorded as failed despite the SDK reporting success. The change affects outcome reporting without changing command execution or output.

You can add or adjust custom eligibility rules. Learn more.

@coderabbitai

coderabbitai Bot commented Nov 3, 2026

Copy link
Copy Markdown
Contributor

Review in Change Stack →

No actionable comments were generated in the recent review.

Walkthrough

The Cursor adapter now marks shell tool results with nonzero exit codes as failed, even when the result status is "success". The lifecycle test covers a command that exits with code 1.

Changes: Cursor shell failure status

Layer / File(s) Summary
Nonzero shell exit handling
packages/provider-cursor/src/server/adapter.ts, packages/provider-cursor/src/server/adapter.test.ts
cursorToolFailed treats a successful shell result with a nonzero exit code as a failure. The lifecycle test verifies that the tool node ends with status "failed".

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

Change: Bug fix

Possibly related PRs

  • pingdotgg/t3code#27907: Upgrades @cursor/sdk to 1.2.0, which provides the shell-result shape used to detect nonzero exit codes.
  • pingdotgg/t3code#23351: Makes a defined command exit code authoritative for success or failure, as this change does for Cursor shell tools.

Suggested labels: size:XS, vouch:unvouched

Suggested reviewers: sunkenintime

Merge Risk: Minimal · up to 4f07a

The shell failure-status regression is addressed and no merge-blocking risk remains.

Pre-merge checks: Passed 4
Check name Status Explanation
Title check Passed The title accurately names the main change: shell commands that exit non-zero are now recorded as failed in the Cursor adapter. It matches the changeset, which updates cursorToolFailed to check a non-…
Description check Passed The description follows the template sections: Problem, Change, Scope and approval, and Verification. The Problem section explains the bug and the expected behavior. The Change section explains the fi…
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: Title check

Explanation

The title accurately names the main change: shell commands that exit non-zero are now recorded as failed in the Cursor adapter. It matches the changeset, which updates cursorToolFailed to check a non-zero exitCode on shell results. The title uses the conventional commit format and is specific.

Full details: Description check

Explanation

The description follows the template sections: Problem, Change, Scope and approval, and Verification. The Problem section explains the bug and the expected behavior. The Change section explains the fix and why it matches the Grok adapter. The Scope section explains why no prior issue exists and lists overlap searches. The Verification section gives specific test commands, red-then-green results, and states that no live Cursor turn was run. The template asks for a model and harness note at the end, and the author provides one. The description meets the requirements.

Finishing Touches
Generate unit tests (beta)
  • Create a new PR
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Warning

Some tools did not complete. Review the errors below.

ast-grep (0.51.1)

ast-grep could not parse rule config: /ast-grep-rules/ast-grep-essentials/rules/java/security/ssl-context.yml

CodeRabbit Verify

  • Run CodeRabbit Verify to test the changes in this pull request.
Recent review info
Run configuration
Commits

Reviewing files that changed from the base of the PR and between d8a829e and 4f07a45.

Files selected for processing: 2
  • packages/provider-cursor/src/server/adapter.test.ts
  • packages/provider-cursor/src/server/adapter.ts

Included review availability: This review used your included allowance. Your plan provides up to 10 included reviews per hour; 1 remain after this review.

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:XS 0-9 changed lines (additions + deletions). vouch:trusted PR author is trusted by repo permissions or the VOUCHED list.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant