Skip to content

[BUG] Shell Snapshots Don't Capture typeset Declarations, Breaking mise and Other Tools #25398

@zeachco

Description

@zeachco

Preflight Checklist

  • I have searched existing issues and this hasn't been reported yet
  • This is a single bug report (please file separate reports for different bugs)
  • 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:

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

  1. Install mise and activate it in .zshrc:

    eval "$(/path/to/mise activate zsh)"
  2. Start a new Claude Code session (creates shell snapshot at ~/.claude/shell-snapshots/)

  3. Run any command that doesn't exist to trigger command_not_found_handler:

    some_nonexistent_command_12345
  4. 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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't workingplatform:macosIssue specifically occurs on macOS

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions