0
Fork 0
mirror of https://github.com/trailofbits/skills.git synced 2026-09-27 09:29:06 +00:00

gh-cli: SessionStart hooks append to CLAUDE_ENV_FILE on every resume/compact; session env exceeds ~8 KB and breaks all Bash calls #341

Open
opened 2026-09-26 18:39:58 +00:00 by aqt-1 · 0 comments
aqt-1 commented 2026-09-26 18:39:58 +00:00 (Migrated from github.com)

Summary

plugins/gh-cli/hooks/setup-shims.sh and persist-session-id.sh append to $CLAUDE_ENV_FILE with an unconditional >> on every SessionStart, including resume and compact. A long-lived session accumulates dozens to hundreds of duplicate export PATH=...shims... / export CLAUDE_SESSION_ID=... lines across its session-env/<sid>/sessionstart-hook-*.sh files.

Impact

Claude Code concatenates those env files and cuts the result off at about 8 KB. Once the duplicates push it past that limit, the cut lands mid-line, and every Bash tool call in that session fails, including echo hi:

/usr/bin/bash: -c: line 103: unexpected EOF while looking for matching `"'

Reproduction: truncating a real bloated env to 8,191 or 8,192 bytes reproduces the error, while 4,096 bytes and the full file both parse fine. We saw this in 7 long-running sessions, with 88–246 lines of duplicates each (Windows 11, Git Bash, gh-cli 1.6.0; 1.6.2 has the same code).

Suggested fix

Only append when the line is not already present in this session's env files:

_env_line="export PATH=\"${shims_dir}:\${PATH}\""
if ! grep -qxF -- "$_env_line" "$(dirname "$CLAUDE_ENV_FILE")"/*.sh 2>/dev/null; then
  echo "$_env_line" >>"$CLAUDE_ENV_FILE" || { echo "gh-cli: failed to write to CLAUDE_ENV_FILE ($CLAUDE_ENV_FILE)" >&2; exit 1; }
fi

Apply the same change to persist-session-id.sh with export CLAUDE_SESSION_ID=\"$session_id\". With this patch, 3 consecutive SessionStart runs leave exactly one line of each. (An alternative is to skip the hook when source is resume or compact, but the dedupe also covers startup re-fires.)

## Summary `plugins/gh-cli/hooks/setup-shims.sh` and `persist-session-id.sh` append to `$CLAUDE_ENV_FILE` with an unconditional `>>` on every SessionStart, including `resume` and `compact`. A long-lived session accumulates dozens to hundreds of duplicate `export PATH=...shims...` / `export CLAUDE_SESSION_ID=...` lines across its `session-env/<sid>/sessionstart-hook-*.sh` files. ## Impact Claude Code concatenates those env files and cuts the result off at about 8 KB. Once the duplicates push it past that limit, the cut lands mid-line, and **every** Bash tool call in that session fails, including `echo hi`: ``` /usr/bin/bash: -c: line 103: unexpected EOF while looking for matching `"' ``` Reproduction: truncating a real bloated env to 8,191 or 8,192 bytes reproduces the error, while 4,096 bytes and the full file both parse fine. We saw this in 7 long-running sessions, with 88–246 lines of duplicates each (Windows 11, Git Bash, gh-cli 1.6.0; 1.6.2 has the same code). ## Suggested fix Only append when the line is not already present in this session's env files: ```bash _env_line="export PATH=\"${shims_dir}:\${PATH}\"" if ! grep -qxF -- "$_env_line" "$(dirname "$CLAUDE_ENV_FILE")"/*.sh 2>/dev/null; then echo "$_env_line" >>"$CLAUDE_ENV_FILE" || { echo "gh-cli: failed to write to CLAUDE_ENV_FILE ($CLAUDE_ENV_FILE)" >&2; exit 1; } fi ``` Apply the same change to `persist-session-id.sh` with `export CLAUDE_SESSION_ID=\"$session_id\"`. With this patch, 3 consecutive SessionStart runs leave exactly one line of each. (An alternative is to skip the hook when `source` is `resume` or `compact`, but the dedupe also covers `startup` re-fires.)
Sign in to join this conversation.
No milestone
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
skills/trailofbits-skills#341
No description provided.