Session-env snapshot file breaks when sourced: unquoted LS_COLORS/SSH_CONNECTION/LESSCLOSE spam 'command not found' on every Bash call
Bug description
Every Bash tool call in a Claude Code session (VS Code extension) prints a wall of spurious command not found / fg: %s: no such job errors to stderr before the actual command runs. It happens even for a no-op (:), confirming it fires during shell/session setup rather than being caused by anything the user typed.
Root cause
~/.claude/session-env/<session-id>/sessionstart-hook-0.sh is written as a raw KEY=VALUE dump (looks like unquoted env output — one env var per line, no shell quoting) and is apparently later sourced as a bash script to replay the session's environment into each new shell. Several completely standard env vars contain shell metacharacters that break when parsed as code instead of data:
| Var | Example value | What happens when sourced |
|---|---|---|
| LS_COLORS | rs=0:di=01;34:ln=01;36:... | Unquoted ; is a command separator. Bash parses LS_COLORS=rs=0:di=01 as a harmless assignment, then hits ;, then tries to run 34:ln=01 as a command → command not found. Repeats for every ;-delimited chunk in the value (~140 errors from one line). |
| SSH_CONNECTION | fe80::...%eth0 59598 fe80::...%eth0 22 | Unquoted spaces. Bash assigns the first token, then tries to run the bare word 59598 as a command → 59598: command not found. |
| LESSCLOSE | /usr/bin/lesspipe %s %s | Same issue, then hits bare word %s. In an interactive shell a bare %s at command position is job-control shorthand for fg %s → fg: %s: no such job. |
| SSH_CLIENT | fe80::...%eth0 59598 22 | Same as SSH_CONNECTION → another 59598: command not found. |
None of these are misconfigured — they're standard dircolors/OpenSSH/lesspipe defaults present on any Debian/Ubuntu box. The bug is in how the harness serializes and replays the env snapshot, not anything under the user's control.
Reproduction
- Open a repo in VS Code with the Claude Code extension, in an environment reached over SSH (so
SSH_CONNECTION/SSH_CLIENTare set) with a normaldircolors-enabled shell. - Ask Claude to run any Bash command, e.g.
hostname. - Observe ~150 lines of
command not found/fg: %s: no such jobon stderr before the command's real output. - Inspect
~/.claude/session-env/<session-id>/sessionstart-hook-0.sh— it's a plain unquotedKEY=VALUEdump containing the offending lines.
Expected behavior
No stderr noise from internal session-state plumbing. Any env var value, regardless of content, should round-trip safely.
Suggested fix
When generating sessionstart-hook-0.sh (or wherever it's consumed), either:
- Serialize with
export -p/declare -poutput (already properly shell-quoted), or - Quote each value when writing, e.g.
printf '%s=%q\n' "$k" "$v", or - Parse the file as data instead of sourcing it as code:
while IFS='=' read -r k v; do export "$k=$v"; done < "$file".
Environment
- Claude Code CLI/extension: 2.1.206 (
claude-vscodeentrypoint, Agent SDK 0.3.206) - OS: Linux (Debian/Ubuntu-based), bash
dircolors: uutils coreutils 0.8.0 (produces correctly-quoted output itself — confirmed not the source of the bug)
3 Comments
Tried to reproduce this on Linux with the released 2.1.233 build: fresh config dir, a SessionStart hook (
echo hi), andLS_COLORS='rs=0:di=01;34:ln=01;36',LESSCLOSE='/usr/bin/lesspipe %s %s',SSH_CONNECTION='1.2.3.4 5 6.7.8.9 22'exported before launch, then ran:with the Bash tool.Result: no errors at all, and
session-env/<session-id>/stayed empty — Claude Code never wrote asessionstart-hook-0.shon its own. That file is only populated by what your hook writes into$CLAUDE_ENV_FILE, and its contents then run as a bash preamble before each Bash command. When I changed the hook toenv >> "$CLAUDE_ENV_FILE", I got your exact symptoms (34:ln=01: command not found,fg: %s: no such job, ...).So an unquoted
env-style dump in that file is the culprit, but it isn't Claude Code writing it. The docs recommend writingexportstatements, or anexport -pbefore/after diff (which quotes values correctly): https://code.claude.com/docs/en/hooks#persist-environment-variablesCould you share (redact values as needed):
~/.claude/settings.json, project.claude/settings.jsonandsettings.local.json, managed settings), and~/.claude/session-env/<session-id>/sessionstart-hook-0.sh?If a hook or wrapper there is dumping raw
envoutput, switching it toexport -p-style output fixes this.🤖 Generated with Claude Code
We weren't able to reproduce this. Could you provide steps to trigger the issue — what you ran, what happened, and what you expected? This issue will be closed automatically if there's no activity within 7 days.
This issue has been automatically locked since it was closed and has not had any activity for 7 days. If you're experiencing a similar issue, please file a new issue and reference this one if it's relevant.