Cursor CLI 2026.08.04 leaks CLAUDE_PLUGIN_ROOT between concurrent plugin hooks

Where does the bug appear (feature/product)?

Cursor CLI

Describe the Bug

Describe the bug

Cursor CLI 2026.08.04-aaa8809 cross-contaminates plugin-scoped environment variables when more than one installed Claude Code-compatible plugin contributes hooks to the same Shell tool call.

A hook belonging to Plugin A starts with the correct CLAUDE_PLUGIN_ROOT and CURSOR_PLUGIN_ROOT. A direct nested Bash child launched by that hook then sees Plugin B’s install root. Plugin A’s fail-closed guards consequently validate or execute files under Plugin B’s root, exit nonzero, and
Cursor blocks every Shell call.

This is not a missing binary: Plugin A’s installed runtime is executable, reports the expected version, passes its self-check, and works when Plugin B is disabled. This is also a plugin-isolation failure because one plugin can resolve another enabled plugin’s files.

Steps to reproduce

  1. Install and enable two Claude Code-compatible plugins, A and B.
  2. Have both contribute a PreToolUse hook matching Bash/Shell. Plugin A’s hook is rooted at ${CLAUDE_PLUGIN_ROOT} and invokes another Bash script below that root.
  3. Temporarily trace non-interactive Bash startup, logging PID, PPID, CLAUDE_PLUGIN_ROOT, and CURSOR_PLUGIN_ROOT.
  4. Start a fresh Cursor CLI session and request a harmless Shell command.

Observed PID/PPID trace, with private plugin names and paths anonymized:

# Both plugins enabled

Plugin A hook entry:
  CLAUDE_PLUGIN_ROOT=~/.claude/plugins/cache/<marketplace-A>/<plugin-A>/<version-A>
  CURSOR_PLUGIN_ROOT=~/.claude/plugins/cache/<marketplace-A>/<plugin-A>/<version-A>

Direct nested Bash child of that Plugin A hook:
  CLAUDE_PLUGIN_ROOT=~/.claude/plugins/cache/<marketplace-B>/<plugin-B>/<version-B>
  CURSOR_PLUGIN_ROOT=~/.claude/plugins/cache/<marketplace-B>/<plugin-B>/<version-B>

Cursor log/result:
  transportMode="stdin"
  hook status="blocked"
  Shell rejected by the guards

Controls performed

  • Disabled Plugin B while retaining Plugin A and the same Cursor build: Plugin A’s hook and every nested child retained Plugin A’s root; all guards exited 0; the Shell command exited 0.
  • Ran the same installed plugins under Claude Code: hooks and Shell commands worked.
  • Invoked Plugin A’s runtime directly: its version and packaged self-check passed.
  • Restarting Cursor and deleting/re-cloning the workspace did not change the failure.

The direct parent/child trace and single-plugin control reproduce the defect independently of the guard’s error message.

Expected behavior

Every plugin hook’s complete process tree must retain that hook’s own plugin root.

Cursor staff has documented that CURSOR_PLUGIN_ROOT should always be the plugin’s installation directory:

Stop hook uses wrong (or different) working directory when executing - #5 by Colin

Regression boundary

  • Fresh sessions fail with Cursor CLI 2026.08.04-aaa8809.
  • A session still running under 2026.07.23-e383d2b was unaffected.
  • The older build appears not to merge installed plugin hooks, so this is only a version boundary—not a claim that its plugin-hook behavior was otherwise correct.
  • New-build logs show installed plugin hooks being merged and executed with transportMode:"stdin".

The evidence suggests—but does not prove—that concurrent plugin-hook executions share mutable shell/environment state, allowing one plugin’s root assignment to overwrite another’s.

Environment

  • macOS 14.5 (23F79), Darwin arm64
  • Cursor CLI: 2026.08.04-aaa8809
  • Cursor desktop: 3.9.16 (042b3c1a4c53f2c3808067f519fbfc67b72cad80)
  • Model: Grok 4.5

Does this stop me from using Cursor?

Yes. With both required plugins enabled, every Shell tool call is blocked. The current workarounds are disabling one plugin or using Claude Code.

I can provide a fuller redacted PID/PPID trace and Cursor CLI log if needed.

Steps to Reproduce

  1. Install and enable two Claude Code-compatible plugins, A and B.

  2. Configure both plugins with a PreToolUse hook matching Bash/Shell. Plugin A’s hook command is rooted at ${CLAUDE_PLUGIN_ROOT} and invokes another Bash script beneath that root.

  3. Temporarily trace non-interactive Bash processes, recording PID, PPID, CLAUDE_PLUGIN_ROOT, and CURSOR_PLUGIN_ROOT.

  4. Start a fresh Cursor CLI 2026.08.04-aaa8809 session and request a harmless Shell command.

  5. Observe that Plugin A’s hook starts with Plugin A’s correct root, but its direct nested Bash child receives Plugin B’s root. Plugin A’s fail-closed guard then exits nonzero and Cursor blocks the Shell call.

Control: disable Plugin B and repeat using the same Cursor build. Plugin A and all its child processes retain Plugin A’s root, every guard exits 0, and the Shell command succeeds.

Expected Behavior

• Each plugin hook’s entire process tree must retain that plugin’s own CLAUDE_PLUGIN_ROOT and CURSOR_PLUGIN_ROOT values.

Nested processes launched by Plugin A must continue resolving Plugin A’s installation directory, regardless of which other plugins have hooks running concurrently. One plugin’s environment must never overwrite or leak into another plugin’s hook process.

With both plugins enabled, the harmless Shell command should pass exactly as it does when Plugin B is disabled and when the same plugins run under Claude Code.

Operating System

MacOS

Version Information

Cursor Agent CLI version: 2026.08.04-aaa8809
Model: grok-4.5
OS: macOS 14.5 (23F79), Darwin arm64
Shell: bash

For AI issues: which model did you use?

Grok 4.5

For AI issues: add Request ID with privacy disabled

934aabdd-19c3-40cd-b2ca-1c503b95742d

Does this stop you from using Cursor

Yes - Cursor is unusable

Hey Sergey,
Quickest unblock: disable one of the two plugins (as you found) and Shell calls stay unblocked. If you own Plugin A’s hook, having its guard resolve paths without relying on the runtime CLAUDE_PLUGIN_ROOT also sidesteps it, but the plugin toggle is the sure workaround for now.

What you’re seeing isn’t intended behavior and isn’t anything in your setup - each plugin hook should keep its own CLAUDE_PLUGIN_ROOT / CURSOR_PLUGIN_ROOT. We’ve let the team know and this is an issue we’re tracking. I’ll follow up here when there’s an update.