Shell snapshot captures base64-encoded functions from git-completion.bash, breaking all Bash commands on Windows

Resolved 💬 5 comments Opened Feb 26, 2026 by RikuDasu Closed Apr 13, 2026

Description

On Windows (Git Bash / MSYS2), shell snapshots capture all shell functions loaded by git-completion.bash (92KB, 80+ functions) as multi-line base64-encoded eval blocks. When the snapshot is later sourced to restore shell state, the base64 lines that span multiple lines are interpreted as individual shell commands, producing ~1,000 command not found errors and completely breaking the Bash tool.

This is distinct from #28061 (pipe buffer truncation of set +o output). The pipe truncation is cosmetic; this base64 corruption renders the shell completely unusable.

Root cause

  1. Git for Windows loads git-completion.bash via /etc/profile.d/git-prompt.sh on every login shell
  2. The snapshot mechanism captures shell functions as eval "$(echo '<base64>' | base64 -d)" > /dev/null 2>&1
  3. For large functions, the base64 string spans multiple lines in the snapshot file
  4. When sourced, only line 1 (eval "$(echo '...') is part of the eval — subsequent lines are bare base64 fragments executed as commands

Corrupted snapshot structure

# Lines 1-58: OK (aliases, shopt)
shopt -u xpg_echo
# Line 59: bare base64 fragment — NOT inside any eval/echo
naXRrKQogICAgICAg
ICAgICAgICAgICAgIGN1cj0iZ2l0ayI7CiAgICAgICAgICAgICAgICAgICAgYnJlYWsKICAgICAg
# ... ~1000 more lines of bare base64 ...
# Line ~1100: end of a base64 block, properly terminated
ZWxpc3QKfQo=' | base64 -d)" > /dev/null 2>&1
# Next function starts...
eval "$(echo 'X19naXRfY2hlY2tvdXRfZGVmYXVsdF9kd2ltX21vZGUgKCkgCnsg...

81 functions are captured this way, totaling ~82KB of base64 content. Every line that isn't inside the eval quotes produces a command not found error.

Why this started happening

This issue became visible after the v2.1.52+ change where BashTool skips login shell (-l) when a snapshot is available. Before this change, snapshots were created but never used for shell restoration, so the corruption was latent.

Environment

  • OS: Windows 10 Pro 10.0.19045
  • Shell: Git Bash (MSYS2) — GNU bash
  • Claude Code: 2.1.59
  • git-completion.bash size: 92,326 bytes (80+ shell functions)

Reproduction

  1. Use Claude Code on Windows with Git Bash (default Git for Windows installation)
  2. Start a session — snapshot is created with base64-encoded git-completion functions
  3. Start another session (or same session) — snapshot is sourced
  4. Every Bash tool call produces ~1,000 lines of command not found errors
  5. Bash output is polluted with 166KB+ of error text, often hiding actual command output

Suggested fix

The snapshot mechanism should either:

  1. Skip function capture entirely when total function size exceeds a threshold (git-completion alone is 92KB)
  2. Use single-line base64 encoding (no line wrapping) so the eval block stays on one line
  3. Quote the multi-line base64 correctly with a heredoc instead of inline echo

Workaround

Create ~/.config/git/git-prompt.sh that checks $CLAUDECODE and skips loading git-completion.bash when running inside Claude Code:

if [ "$CLAUDECODE" = "1" ]; then
    # Skip git-completion.bash to avoid snapshot corruption
    PS1='\[\033[32m\]\u@\h \[\033[33m\]\w\[\033[0m\]\n$ '
else
    # Normal terminal: load git-completion as usual
    . "$COMPLETION_PATH/git-completion.bash"
    . "$COMPLETION_PATH/git-prompt.sh"
    # ... full PS1 with __git_ps1 ...
fi

Related

  • #28061 — Pipe buffer truncation (different symptom, same snapshot mechanism)

View original on GitHub ↗

This issue has 5 comments on GitHub. Read the full discussion on GitHub ↗