Repository navigation
[Bug] Cursor adapter: false "Shell/Read blocked" reports caused by shell-tool name mismatch + native-exec rejections #399
Copy link
Copy link
Closed
Labels
bugSomething isn't workingSomething isn't working
Description
Summary
On Cursor-backed models, agents repeatedly tell the user that shell/read access is blocked even when Codex is already running with full sandbox access and the Codex shell bridge tool still works.
This is not a missing-permissions bug. It is a Cursor adapter / tool-catalog / messaging bug:
- Cursor-native
Shell/Read/Grep/LSare rejected by policy (defaultnativeLocalExecoff). - OpenCodex guidance and rejection text push
exec_command. - The actually working Codex shell bridge is often advertised / callable as
shell_commandand/or the long MCP display name (mcp_opencodex-responses_shell_command/mcp_opencodex-responses_exec_command). - Tool-catalog truncation changes which exact name is visible turn-to-turn.
- Models treat the resulting "tool not found" / native-exec rejection as a hard sandbox block and emit user-facing lines like:
Shell access is blocked hereShell and Read are blocked in this environment
Observed across multiple Codex Desktop chats on Cursor models (including while diagnosing this issue).
Expected
With Codex full-access sandbox already enabled:
- Calling the Codex shell bridge succeeds.
- If Cursor-native Shell/Read are unavailable, rejection text should clearly say "use Codex bridge tool X (aliases: ...)", not sound like a sandbox denial.
- Agents should not tell the user that shell/read are blocked unless the Codex bridge shell tool itself fails.
- The shell bridge tool should remain available even when the Cursor client-tool catalog is truncated.
Actual
- Cursor-native Shell/Read get rejected with copy that points at
exec_command. - The live callable shell tool name flips between turns among:
shell_commandexec_command- long
mcp_opencodex-responses_*display names - occasionally Cursor-native
Shellappearing in guidance/catalog text
- Models then emit false "blocked" commentary even though a later
shell_command/ bridge call works in the same chat. - Catalog truncation notes (
Cursor's transport limit allows N of M client tools this turn) amplify the confusion.
Evidence / code pointers
Relevant OpenCodex paths:
src/adapters/cursor/tool-definitions.ts- hardcodes shell guidance around
exec_command - warns against neighboring-agent tools
Read/Grep/Glob/Bash/LS - mentions long display alias
mcp_opencodex-responses_exec_command
- hardcodes shell guidance around
src/adapters/cursor/request-builder.tsapplyCursorToolBudget/toolPriority/catalogLimitNote- truncation can omit many tools; shell bridge is not specially pinned beyond generic bare-tool priority
src/adapters/cursor/native-exec-shell.ts- rejection: Cursor native shell unavailable; use
exec_command
- rejection: Cursor native shell unavailable; use
src/adapters/cursor/native-exec-fs.ts- rejection: Cursor native filesystem read/ls/grep unavailable; use
exec_command/apply_patch
- rejection: Cursor native filesystem read/ls/grep unavailable; use
src/adapters/cursor/exec-policy.ts- default native local exec is off unless explicitly opted in
- docs:
docs-site/src/content/docs/reference/configuration.md- documents
unsafeAllowNativeLocalExecas an intentional opt-in, not the default path
- documents
Live reproduction pattern (redacted):
- Use a
cursor/*model through OpenCodex. - Ensure Codex sandbox is full-access / approval never.
- Ask the agent to inspect local files/run shell.
- Observe either:
- wrong tool name (
Shell/ missing short name) fails, or - Cursor-native Shell/Read rejected with "use exec_command"
- wrong tool name (
- Agent announces shell/read are blocked.
- Same chat can then succeed with
shell_command/ long MCP shell alias.
Why this is harmful
- Users waste time chasing phantom permission problems.
- Agents abandon working shell paths and invent alternate broken tool names.
- Multi-turn work becomes flaky because catalog truncation + naming drift changes the callable shell identifier every turn.
Proposed fix
Minimum durable fix set:
- Unify the shell tool name across catalog
shell_type, Cursor guidance, rejection messages, and docs.- Today
shell_commandandexec_commandconflict.
- Today
- Pin the shell bridge tool through catalog truncation in
applyCursorToolBudget/toolPriorityso truncation can drop niche MCP tools but never the shell bridge (and ideally also keepapply_patch). - Rewrite rejection/guidance copy:
- say Cursor-native Shell/Read are disabled by policy
- point to the exact Codex bridge tool + aliases
- explicitly state this is not a sandbox denial when Codex full-access is already active
- Add anti-false-block guidance:
- never tell the user shell/read are blocked unless the Codex bridge shell tool also fails
- if a shell alias is missing, retry listed aliases instead of escalating to "blocked" language
- Make alias resolution boring and bidirectional so all of these resolve to one backend tool:
shell_commandexec_commandmcp_opencodex-responses_shell_commandmcp_opencodex-responses_exec_command
- Regression tests covering:
- full-access sandbox
- native Cursor Shell/Read rejected
- bridge shell still works
- truncated catalogs still retain bridge shell
- guidance/rejection text does not claim "Shell access is blocked"
Non-goals / not the fix
- Do not treat this as a Codex sandbox_mode / approval_policy problem.
- Do not require enabling
unsafeAllowNativeLocalExecas the primary solution. - That flag remains an intentional escape hatch for Cursor-native local exec; the default path should remain the Codex bridge, but without false "blocked" UX.
Environment (redacted)
- Host: Windows
- Client: Codex Desktop + OpenCodex Cursor provider path
- Model family:
cursor/* - Codex sandbox already full-access
- Issue filing account is a fork collaborator account; no local paths / tokens / private IDs included
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
bugSomething isn't workingSomething isn't working
Activity
Ingwannu commentedon Jul 24, 2026
Thanks for the concrete tool-name and native-exec analysis. The implementation is being tracked in draft PR #402. We will keep this issue open until that PR proves the shell-name normalization and native-exec rejection behavior with focused regression tests and passes review; the issue should close only with the verified merge.
fix(cursor): stop false shell/read blocked reports (#399)
fix(cursor): rewrite shell bridge cmd args to command (#399)
Merge pull request #402 from Wibias/codex/fix-issue-399-shell-bridge-…
fix(kiro): reserve catalog room for the code-mode execution path
fix(kiro): reserve catalog room for the code-mode execution path
fix(cursor): stop false shell/read blocked reports (lidge-jun#399)
fix(cursor): rewrite shell bridge cmd args to command (lidge-jun#399)
fix(cursor): harden shell-bridge alias admission and budget pinning (l…
fix(cursor): address CodeRabbit shell-bridge review (lidge-jun#399)
fix(cursor): drop dead pin-eviction loop after CodeRabbit review (lid…
fix(cursor): stop models narrating native shell as blocked (lidge-jun…
fix(cursor): address CodeRabbit shell-choice and policy assertions (l…
fix(cursor): harden shell-bridge choice, arg normalize, and allowed_t…
Merge pull request lidge-jun#402 from Wibias/codex/fix-issue-399-shel…
fix(kiro): reserve catalog room for the code-mode execution path