Skip to content

Expose CLAUDE_SESSION_ID as environment variable in tool execution context #47018

Description

@farreachchad

Problem

Tools and hooks invoked within a Claude Code session have no reliable way to identify which session they belong to at the shell level. While ${CLAUDE_SESSION_ID} string substitution was added for skill prompt text in v2.1.9, the session ID is not available as an environment variable in the Bash tool execution context or in hook shell commands.

Current state (v2.1.104)

Mechanism Available? Notes
$CLAUDE_SESSION_ID env var in Bash tool No echo $CLAUDE_SESSION_ID returns empty
${CLAUDE_SESSION_ID} in skill prompt text Yes (since 2.1.9) String substitution only — not accessible from shell commands
Shell PID ($$) mapping to Claude PID No $$ returns a child bash PID; $PPID shows 1 (orphaned) on Windows/MinGW
Session JSON files in ~/.claude/sessions/ Yes Contains sessionId + pid, but tools can't discover which file is theirs
snapshot-unknown.txt Broken Writes session=unknown — cannot resolve session ID

Evidence

# Only these Claude env vars exist:
$ env | grep CLAUDE
CLAUDECODE=1
CLAUDE_CODE_ENTRYPOINT=cli
CLAUDE_CODE_EXECPATH=C:\Users\Chad\.local\bin\claude.exe

# No session ID:
$ echo "$CLAUDE_SESSION_ID"
(empty)

# PID chain is broken (MinGW on Windows):
$ echo "$$=$$ PPID=$PPID"
$$=1338 PPID=1

# But the Claude process and session data exist:
$ tasklist /FI "PID eq 57116"
claude.exe  57116  Console  1  636,128 K

$ cat ~/.claude/sessions/57116.json
{"pid":57116,"sessionId":"736848ea-e359-4f8c-9e44-7f2dea2ad9b1",...}

Use case

Custom skills and hooks that write per-session files (e.g., session logs, caches, temp state) need a stable unique key to avoid collisions when multiple sessions run concurrently. Today, workarounds like {repo}-{branch} are fragile — two sessions in the same repo on the same branch will collide.

The skill prompt substitution (${CLAUDE_SESSION_ID}) partially helps, but requires the model to relay the value into shell commands, which is indirect and unreliable for hooks that run without model mediation.

Proposed solution

Set CLAUDE_SESSION_ID as an environment variable in the tool/hook execution context, matching the sessionId from the session JSON. This would join the existing CLAUDECODE, CLAUDE_CODE_ENTRYPOINT, and CLAUDE_CODE_EXECPATH variables.

# Desired behavior:
$ echo "$CLAUDE_SESSION_ID"
736848ea-e359-4f8c-9e44-7f2dea2ad9b1

Secondary fix

The snapshot file (~/.claude/sessions/snapshot-unknown.txt) should write the actual session ID instead of session=unknown.

Environment

  • Claude Code v2.1.104
  • Windows 11 Pro (MinGW64 bash)
  • Also likely affects macOS/Linux (PID mapping may work better there, but env var is still missing)

Metadata

Metadata

Assignees

No one assigned

    Labels

    duplicateThis issue or pull request already exists

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions