Expose CLAUDE_SESSION_ID as environment variable in tool execution context
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)
This issue has 3 comments on GitHub. Read the full discussion on GitHub ↗