Skip to content

fix: use runtime fallback for zoxide cd function#591

Open
ki11e6 wants to merge 3 commits intobasecamp:masterfrom
ki11e6:fix/zoxide-cd-alias-fallback
Open

fix: use runtime fallback for zoxide cd function#591
ki11e6 wants to merge 3 commits intobasecamp:masterfrom
ki11e6:fix/zoxide-cd-alias-fallback

Conversation

@ki11e6
Copy link
Copy Markdown

@ki11e6 ki11e6 commented Dec 31, 2025

Summary

  • Removes alias cd='z' from defaults/bash/aliases
  • Adds a cd() function in defaults/bash/init with runtime fallback to builtin cd

Problem

The cd command fails with bash: command not found: __zoxide_z in non-interactive shell environments (e.g., Claude Code CLI, scripts, CI/CD pipelines).

Root cause: Zoxide's __zoxide_z function is not available in non-interactive shells because eval "$(zoxide init bash)" doesn't properly define functions in these contexts. See: anthropics/claude-code#2407

Previous Fix Attempt (didn't fully work)

# Source-time check - only creates alias if function exists at source time
if declare -f __zoxide_z &> /dev/null; then
  alias cd='z'
fi

Why it failed: This checks only once when the file is sourced. In some environments, the shell state can become inconsistent (functions defined but later unavailable), or tools like mise can override the cd function after our alias is set.

New Fix (runtime fallback)

cd() {
  if declare -f __zoxide_z &>/dev/null; then
    __zoxide_z "$@"
  else
    builtin cd "$@"
  fi
}

Why this works:

  1. Checks at execution time whether __zoxide_z is available
  2. Uses zoxide when available (interactive shells)
  3. Falls back gracefully to builtin cd when not (non-interactive shells)
  4. Never produces errors in any environment

Test Results

Environment cd behavior Result
Interactive shell Uses __zoxide_z ✅ zoxide works
Non-interactive shell Falls back to builtin cd ✅ no errors
Claude Code CLI Falls back to builtin cd ✅ no errors

Test plan

  • Verified cd uses zoxide in interactive shells
  • Verified cd falls back to builtin in non-interactive shells
  • Verified no __zoxide_z errors in any environment
  • Verified .., ... aliases still work in interactive shells

Only alias cd to z if __zoxide_z function was properly initialized.
This prevents broken alias errors in non-interactive shells (e.g., Claude Code)
where zoxide init may not fully set up the z function.
@ki11e6 ki11e6 force-pushed the fix/zoxide-cd-alias-fallback branch from 65e8247 to d5c5606 Compare January 2, 2026 05:52
@ki11e6 ki11e6 closed this Jan 3, 2026
Replace source-time alias check with runtime function fallback.
This approach checks if __zoxide_z is available at execution time,
allowing graceful fallback to builtin cd in non-interactive shells
(e.g., Claude Code) while still supporting zoxide in interactive shells.

Ref: anthropics/claude-code#2407
@ki11e6 ki11e6 reopened this Jan 9, 2026
@ki11e6 ki11e6 changed the title fix: move cd alias into zoxide init block fix: use runtime fallback for zoxide cd function Jan 9, 2026
Copy link
Copy Markdown
Contributor

@Kasui92 Kasui92 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it's more correct to separate init from aliases.
In this #562 I'm introducing the same configuration that was used on Omarchy, which solves this problem.

if command -v zoxide &> /dev/null; then
  alias cd="zd"
  zd() {
    if [ $# -eq 0 ]; then
      builtin cd ~ && return
    elif [ -d "$1" ]; then
      builtin cd "$1"
    else
      z "$@" && printf "\U000F17A9 " && pwd || echo "Error: Directory not found"
    fi
  }
fi

@ki11e6
Copy link
Copy Markdown
Author

ki11e6 commented Jan 10, 2026

Thanks for the feedback @Kasui92! Your approach from Omarchy is actually much better.

Happy to defer to PR #562 if it's addressing this more comprehensively. Should I close this PR in favor of that one?

Improved approach inspired by Omarchy (thanks @Kasui92!):
- Use builtin cd directly for no args (home) and existing directories
- Only use zoxide for fuzzy matching
- Fallback to builtin cd if zoxide unavailable (non-interactive shells)

More efficient - skips function check for common cases.
@ki11e6 ki11e6 force-pushed the fix/zoxide-cd-alias-fallback branch from e5a938a to e550192 Compare January 10, 2026 05:34
Copy link
Copy Markdown
Contributor

@Kasui92 Kasui92 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think so, that might be enough, even just to have a similar alignment with what's being done on Omarchy.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants