Shell Function Inheritance Issue - Zoxide and Dynamic Functions Fail in Bash Tool

Status Closed — not planned
Maintainer reply None cached
Activity 12 comments · opened Jun 21, 2025 · closed Jan 10, 2026

Claude Code Bug Report: Shell Function Inheritance Issue with Zoxide

Bug Summary

Claude Code's Bash tool execution environment fails to properly inherit/execute shell functions, specifically breaking zoxide functionality that depends on __zoxide_z and related functions.

Environment

  • Claude Code Version: 1.0.18
  • OS: Linux (WSL2) - Ubuntu on Windows
  • Shell: zsh 5.9
  • Kernel: Linux 6.6.87.2-microsoft-standard-WSL2
  • Zoxide Version: 0.9.8 (installed at ~/.local/bin/zoxide)

Expected Behavior

When zoxide is properly configured in ~/.zshrc with eval "$(zoxide init zsh)", the cd command should work seamlessly using zoxide's smart directory jumping functionality.

Actual Behavior

$ cd /some/path
z:1: command not found: __zoxide_z

Reproduction Steps

  1. Install zoxide: curl -sS https://raw.githubusercontent.com/ajeetdsouza/zoxide/main/install.sh | bash
  2. Add to ~/.zshrc: eval "$(zoxide init zsh)"
  3. Source ~/.zshrc: source ~/.zshrc
  4. In normal terminal: cd some_path works perfectly
  5. In Claude Code Bash tool: cd some_path fails with "command not found: __zoxide_z"

Investigation Results

What Works in Normal Shell

$ zoxide --version
zoxide 0.9.8

$ which zoxide
/home/chris/.local/bin/zoxide

$ type __zoxide_z
__zoxide_z is a shell function from ~/.zshrc

What Fails in Claude Code Bash Tool

$ zoxide --version
zoxide 0.9.8

$ type __zoxide_z
z:1: command not found: __zoxide_z

$ eval "$(zoxide init zsh)"
# Appears to execute without error, but functions are not available

Root Cause Analysis

The issue appears to be that Claude Code's Bash tool execution context:

  1. Does not properly inherit shell functions defined in ~/.zshrc
  2. Cannot execute eval statements that define shell functions dynamically
  3. Persists broken aliases even after unalias/unset attempts

Technical Details

Zoxide Initialization Code

When zoxide init zsh runs, it generates shell functions like:

function __zoxide_z() {
    if [[ "$#" -eq 0 ]]; then
        __zoxide_cd ~
    elif [[ "$#" -eq 1 ]] && { [[ -d "$1" ]] || [[ "$1" = '-' ]] || [[ "$1" =~ ^[-+][0-9]$ ]]; }; then
        __zoxide_cd "$1"
    else
        \builtin local result
        result="$(\command zoxide query --exclude "$(__zoxide_pwd)" -- "$@")" && __zoxide_cd "${result}"
    fi
}

Failed Workarounds Attempted

  1. Manual function definition: Functions defined but not accessible
  2. Re-sourcing ~/.zshrc: No effect in Claude Code context
  3. Direct eval execution: Appears to succeed but functions unavailable
  4. Clearing completion cache: rm ~/.zcompdump*; compinit - no effect
  5. Alternative initialization: zoxide init zsh --no-cmd - same issue

Impact

This affects any development workflow that relies on:

  • Zoxide for smart directory navigation
  • Any shell functions defined in user configurations
  • Dynamic shell function generation via eval

Expected Fix

Claude Code's Bash tool should:

  1. Properly inherit shell functions from the user's shell environment
  2. Support dynamic function definition via eval
  3. Maintain function persistence across command executions within the same session

Workaround

Created fix script at /mnt/c/ats/ph1t/fix_zoxide.sh that manually defines functions, but this doesn't address the underlying shell inheritance issue.

Business Impact

This significantly impacts developer productivity in Claude Code, as modern shell productivity tools (zoxide, starship, fzf integration) rely on shell functions that don't work in Claude Code's execution environment.

Supporting Files

  • Zoxide fix script: /mnt/c/ats/ph1t/fix_zoxide.sh
  • Shell configuration: ~/.zshrc (contains proper zoxide initialization)

Additional Context

This issue was discovered during integration testing of a Neovim plugin (Maxi.nvim) where directory navigation was failing consistently in Claude Code but working perfectly in normal terminal sessions.

View original on GitHub ↗

12 Comments

maherbeg · 1 year ago

I've run into a similar issue while running in Fish where we also have a direnv integration to load a bunch of environment specific settings. If I ask Claude to execute a command but prepend it with fish -i -c, it works with the correctly loaded environment. I have a bash script it is running that requires a newer version of bash, but it keeps picking up /bin/bash instead causing bash scripting errors with the version of bash.

serpent213 · 1 year ago

Quick fix, if you don't require enhanced zsh behaviour inside Claude Code:

SHELL=/bin/bash claude
matheusml · 1 year ago

The same is happening here.

ericboehs · 11 months ago

I asked Claude to fix this and here's what it came up with:

# ~/.zshrc

# Zoxide (cd replacement)
# Only initialize in interactive shells to avoid issues with Claude Code
[[ $- == *i* ]] && [ -z "$DISABLE_ZOXIDE" ] && eval "$(zoxide init --cmd cd zsh)"

It could probably be simplified to just:

[[ $- == *i* ]] && eval "$(zoxide init --cmd cd zsh)"
antonioacg · 11 months ago

I think it would be really useful if we could make Claude actually use zoxide. How may times have it tried to change to a directory it was already on? Lol

lukemelnik · 11 months ago

This is working for me, forcing claude to use bash:

claude() {
  SHELL=/bin/bash command claude "$@"
}
````
include · 10 months ago

@lukemelnik thanks for your hint.
I had to make small adjustments to allow me to load my .env and also process additional parameters to claude cmd.

claude() {
  SHELL=/bin/bash bash -c '[[ -f .env ]] && source .env; exec claude "$@"' _ "$@"
}
antonioacg · 10 months ago

Got zoxide working, but with a really hacky solution, apparently only private function were not inherited, so...

# Initialize zoxide with 'cd' command (disable doctor warnings)
export _ZO_DOCTOR=0
eval "$(zoxide init --cmd cd zsh | sed -E 's/(^|[^_])__([a-zA-Z_])/\1\2/g')"
github-actions[bot] · 8 months ago

This issue has been inactive for 30 days. If the issue is still occurring, please comment to let us know. Otherwise, this issue will be automatically closed in 30 days for housekeeping purposes.

dotnich-io · 8 months ago

I found it easier to disable zoxide for Claude, like this.

github-actions[bot] · 7 months ago

This issue has been automatically closed due to 60 days of inactivity. If you're still experiencing this issue, please open a new issue with updated information.

github-actions[bot] · 7 months ago

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.