claude-code - 💡(How to fix) Fix Feature request: set distinct CLAUDE_CODE_ENTRYPOINT (or similar env var) for Agent-spawned sub-agents [1 participants]

Official PRs (…)
ON THIS PAGE

Recommended Tools

×6

Utilities matched from this issue’s tags and category — try them while you read without losing context.

GitHub issue graph ai analysis

Paste a GitHub issue URL. We fetch that issue, discover linked issues from bodies/comments/timeline, collect linked pull requests, and produce a structured English report.

The report is written in English Markdown for sharing and archival.

Helpful · Quick feedback

Loading…
GitHub stats
anthropics/claude-code#54541Fetched 2026-04-30 06:42:49
View on GitHub
Comments
0
Participants
1
Timeline
3
Reactions
0
Author
Participants
Timeline (top)
labeled ×3

When Claude Code spawns a sub-agent via the Agent tool, the sub-agent's process inherits CLAUDE_CODE_ENTRYPOINT='cli' from its parent — making it indistinguishable from the main-thread session via env-var inspection alone.

This breaks any custom hook (PreToolUse, PostToolUse, etc.) that wants to apply different policy based on whether a tool call originates from the main thread vs a sub-agent.

Root Cause

Custom hook authors want to enforce per-actor policy without resorting to ancestor PID walking. A single distinguishing env var would make such hooks robust and version-stable.

Fix Action

Fix / Workaround

Workaround (in current versions)

Process-tree marker file: a PreToolUse hook on Agent writes a marker file when a sub-agent dispatch fires; the main hook walks parent PIDs to detect ancestor markers. Works but adds complexity to userspace hook code that this internal change would eliminate.

Code Example

CLAUDE_CODE_ENTRYPOINT='cli'             ← same as main thread
CLAUDE_PROJECT_DIR='UNSET'                ← differs from main, but unset is inconsistent across spawn types
CLAUDECODE='1'                            ← same as main thread
AI_AGENT='claude-code/2.1.122/agent'      ← same as main thread
parent_pid=<intermediate-claude-PID>      ← differs but only via process tree walking

---

# Sub-agent detection:
# - CLAUDE_CODE_ENTRYPOINT env var: \"cli\" = main thread, \"local-agent\" = sub-agent.
# - If we can't reliably detect sub-agent context, we LOG ONLY (exit 0) instead of
#   blocking (exit 2), to avoid bricking legitimate agent threads.
RAW_BUFFERClick to expand / collapse

Summary

When Claude Code spawns a sub-agent via the Agent tool, the sub-agent's process inherits CLAUDE_CODE_ENTRYPOINT='cli' from its parent — making it indistinguishable from the main-thread session via env-var inspection alone.

This breaks any custom hook (PreToolUse, PostToolUse, etc.) that wants to apply different policy based on whether a tool call originates from the main thread vs a sub-agent.

Empirical observation (Claude Code 2.1.122 on macOS)

Two general-purpose sub-agents spawned in parallel via the Agent tool both reported identical environment values:

CLAUDE_CODE_ENTRYPOINT='cli'             ← same as main thread
CLAUDE_PROJECT_DIR='UNSET'                ← differs from main, but unset is inconsistent across spawn types
CLAUDECODE='1'                            ← same as main thread
AI_AGENT='claude-code/2.1.122/agent'      ← same as main thread
parent_pid=<intermediate-claude-PID>      ← differs but only via process tree walking

The Team Lead's own env on the same session is identical on every key except parent_pid. There is no env-var-only discriminator in current Claude Code.

Use case

Hook-based enforcement of a 'main thread only orchestrates; sub-agents do the work' invariant. The natural implementation is:

  • PreToolUse hook checks whether this tool call is from main thread or sub-agent.
  • Allow all tools for sub-agents.
  • Restrict main thread to a permitted set (Agent, SendMessage, TaskCreate, etc.).

The hook's is_sub_agent() function naturally tries to read CLAUDE_CODE_ENTRYPOINT. Per the existing comment at the top of one such hook implementation:

# Sub-agent detection:
# - CLAUDE_CODE_ENTRYPOINT env var: \"cli\" = main thread, \"local-agent\" = sub-agent.
# - If we can't reliably detect sub-agent context, we LOG ONLY (exit 0) instead of
#   blocking (exit 2), to avoid bricking legitimate agent threads.

The detection cannot be made reliable today because the env var simply doesn't differ.

Proposed change

When Claude Code spawns a sub-agent via the Agent tool, set one of:

  • CLAUDE_CODE_ENTRYPOINT=local-agent (or another value distinct from cli); OR
  • CLAUDE_AGENT_ID=<id> populated only for sub-agents; OR
  • CLAUDE_AGENT_DEPTH=<n> (1 for main thread, 2+ for sub-agents).

Any of the three would solve the problem. The first option matches an existing pattern that hook authors have already started building against.

Workaround (in current versions)

Process-tree marker file: a PreToolUse hook on Agent writes a marker file when a sub-agent dispatch fires; the main hook walks parent PIDs to detect ancestor markers. Works but adds complexity to userspace hook code that this internal change would eliminate.

Why this matters

Custom hook authors want to enforce per-actor policy without resorting to ancestor PID walking. A single distinguishing env var would make such hooks robust and version-stable.

extent analysis

TL;DR

Set a distinct environment variable for sub-agents, such as CLAUDE_CODE_ENTRYPOINT=local-agent, to enable reliable detection and policy enforcement.

Guidance

  • Introduce a new environment variable, e.g., CLAUDE_AGENT_ID or CLAUDE_AGENT_DEPTH, to distinguish sub-agents from the main thread.
  • Update the Agent tool to set this variable when spawning sub-agents.
  • Modify the is_sub_agent() function in the PreToolUse hook to check for the new environment variable.
  • Consider implementing a fallback mechanism, such as the proposed workaround using a process-tree marker file, for current versions.

Example

# Example of updated is_sub_agent() function
def is_sub_agent():
    return os.environ.get('CLAUDE_CODE_ENTRYPOINT') == 'local-agent'

Notes

The proposed change requires updates to the Claude Code Agent tool and the PreToolUse hook implementation. The workaround using a process-tree marker file can be used in current versions but adds complexity to userspace hook code.

Recommendation

Apply the proposed change by setting a distinct environment variable for sub-agents, such as CLAUDE_CODE_ENTRYPOINT=local-agent, to enable reliable detection and policy enforcement. This approach is more robust and version-stable than relying on ancestor PID walking or other workarounds.

Vote matrix · Quick signals

Works
Did the solution work? Tap to confirm.
Easy Fix
Was it a quick fix?
Time Saver
Did it save you time?
Blocking
Was it severely blocking?
Common Issue
Are others likely hitting this too?
Flaky / Intermittent
Is it intermittent?
Verified / Reproducible
Can you reproduce it reliably?
Loading…

Still need to ship something?

×6

Another batch ranked right after the header list — different links, same matching logic.

Back to top recommendations

TRENDING

claude-code - 💡(How to fix) Fix Feature request: set distinct CLAUDE_CODE_ENTRYPOINT (or similar env var) for Agent-spawned sub-agents [1 participants]