[BUG] Shell Snapshots Don't Capture `typeset` Declarations, Breaking mise and Other Tools
Preflight Checklist
- [x] I have searched existing issues and this hasn't been reported yet
- [x] This is a single bug report (please file separate reports for different bugs)
- [x] I am using the latest version of Claude Code
What's Wrong?
Claude Code's shell snapshot mechanism captures function definitions but not variable type declarations (e.g., typeset -gA for associative arrays). This causes runtime errors when captured functions reference arrays that were declared during shell initialization but aren't included in the snapshot.
This is part of a broader pattern of shell snapshot problems:
- #21832 - Shell snapshots prepend
/usr/binto PATH, breaking conda - #20464 - Shell snapshot breaks zoxide
__zoxide_zfunction - #16545 - Shell snapshot duplicates
--prefix for aliases - #22730 - Shell snapshot overwrites PATH, breaking Homebrew tools
- #24564 - Shell snapshot subprocesses leaked (zombies)
What Should Happen?
When mise activates in .zshrc, it generates:
typeset -gA _mise_cnf_tried # Declares associative array
command_not_found_handler() {
_mise_cnf_tried["$cmd"]=1 # Uses it as associative array
}
The snapshot should capture both the typeset -gA declaration and the function. Currently it only captures the function, so zsh doesn't know _mise_cnf_tried is an associative array and fails when trying to use string keys.
Error Messages/Logs
command_not_found_handler:17: _mise_cnf_tried: assignment to invalid subscript range
Steps to Reproduce
- Install mise and activate it in
.zshrc:
``bash``
eval "$(/path/to/mise activate zsh)"
- Start a new Claude Code session (creates shell snapshot at
~/.claude/shell-snapshots/)
- Run any command that doesn't exist to trigger
command_not_found_handler:
``bash``
some_nonexistent_command_12345
- Observe the error above
Root cause verification:
# Check that the snapshot is missing the declaration:
grep -n "typeset -gA _mise_cnf_tried" ~/.claude/shell-snapshots/snapshot-zsh-*.sh
# Returns nothing
# But the function that uses it IS captured:
grep -n "command_not_found_handler" ~/.claude/shell-snapshots/snapshot-zsh-*.sh
# Returns the function definition
Claude Model
Opus
Is this a regression?
I don't know
Claude Code Version
1.0.17 (Claude Code)
Platform
Anthropic API
Operating System
macOS
Terminal/Shell
iTerm2 or alacritty or kitty | zellij | zsh
Additional Information
Impact: This affects any tool using associative arrays in shell functions (mise, asdf, custom frameworks, etc.). Developers with multiple environment tools (nix, devbox, mise) are especially affected.
Current Workaround: Manually patch each snapshot file by adding the missing declarations before command_not_found_handler():
typeset -gA _mise_cnf_tried
_mise_fallback() {
local _cmd="$1"; shift
if typeset -f _command_not_found_handler >/dev/null; then
_command_not_found_handler "$_cmd" "$@"
return $?
else
print -u2 -- "zsh: command not found: $_cmd"
return 127
fi
}
This requires manually editing ~/.claude/shell-snapshots/snapshot-zsh-*.sh after each regeneration.
Design consideration: The snapshot optimization saves ~200-500ms per command but creates correctness issues. The time to load .zshrc has no token cost - it's just wall-clock time. However, debugging snapshot issues consumes thousands of tokens. A setting like shell.useSnapshots: false would let users with complex shell setups opt for correctness over speed.
Note: Adding typeset -gA _mise_cnf_tried to .zshrc before mise activation doesn't help - the declaration still isn't captured in the snapshot.
This issue has 3 comments on GitHub. Read the full discussion on GitHub ↗