Bug
When CDPATH is set (common with zsh/bash users who use zoxide or custom navigation), every bin/ script silently fails because cd prints the resolved path to stdout, doubling the output of $(cd ... && pwd).
Root cause
Bash behavior: when CDPATH is set and cd resolves a directory through CDPATH, it prints the absolute path to stdout. This means:
# With CDPATH='.:/Users/me:/Users/me/Workspaces'
GSTACK_DIR="$(cd "$(dirname "$0")/.." && pwd)"
# cd outputs: /path/to/gstack
# pwd outputs: /path/to/gstack
# GSTACK_DIR = "/path/to/gstack\n/path/to/gstack" (two lines!)
This corrupts VERSION_FILE, CACHE_FILE, and every other path derived from GSTACK_DIR.
Specific impact on gstack-update-check: VERSION_FILE becomes a two-line string, [ -f "$VERSION_FILE" ] fails, LOCAL stays empty, script exits at line 68 (if [ -z "$LOCAL" ]; then exit 0; fi). Result: upgrade check always reports "up to date" regardless of actual version.
Affected scripts (18 total)
All scripts in bin/ that use the $(cd "$(dirname "$0")/.." && pwd) pattern:
- gstack-update-check (most impactful - blocks all upgrade detection)
- gstack-telemetry-log, gstack-telemetry-sync
- gstack-community-dashboard, gstack-uninstall
- gstack-timeline-log, gstack-timeline-read
- gstack-specialist-stats, gstack-review-log, gstack-review-read
- gstack-platform-detect, gstack-repo-mode, gstack-relink
- gstack-learnings-log, gstack-learnings-search
- gstack-extension, dev-setup, dev-teardown
Reproduction
export CDPATH='.:/Users/me:/Users/me/Workspaces'
~/.claude/skills/gstack/bin/gstack-update-check --force
# No output - silently exits, never checks remote VERSION
Fix
Redirect cd stdout to /dev/null in all path resolution patterns:
# Before (broken with CDPATH)
GSTACK_DIR="$(cd "$(dirname "$0")/.." && pwd)"
# After (works with any CDPATH)
GSTACK_DIR="$(cd "$(dirname "$0")/.." >/dev/null && pwd)"
Or use CDPATH= to suppress:
GSTACK_DIR="$(CDPATH= cd "$(dirname "$0")/.." && pwd)"
Environment
- gstack v0.15.9.0 (also affects v0.11.10.0 and likely all versions)
- macOS 14 (Darwin 24.6.0), bash 5.x
- CDPATH set via zoxide (
eval "$(zoxide init bash)" adds alias cd=z)
- Also reproducible with manual
CDPATH export
Workaround
Users can unset CDPATH before running gstack, but since gstack-update-check runs automatically in skill preambles, there is no practical workaround without patching the scripts.
Bug
When
CDPATHis set (common with zsh/bash users who use zoxide or custom navigation), everybin/script silently fails becausecdprints the resolved path to stdout, doubling the output of$(cd ... && pwd).Root cause
Bash behavior: when
CDPATHis set andcdresolves a directory throughCDPATH, it prints the absolute path to stdout. This means:This corrupts
VERSION_FILE,CACHE_FILE, and every other path derived fromGSTACK_DIR.Specific impact on
gstack-update-check:VERSION_FILEbecomes a two-line string,[ -f "$VERSION_FILE" ]fails,LOCALstays empty, script exits at line 68 (if [ -z "$LOCAL" ]; then exit 0; fi). Result: upgrade check always reports "up to date" regardless of actual version.Affected scripts (18 total)
All scripts in
bin/that use the$(cd "$(dirname "$0")/.." && pwd)pattern:Reproduction
Fix
Redirect
cdstdout to/dev/nullin all path resolution patterns:Or use
CDPATH=to suppress:GSTACK_DIR="$(CDPATH= cd "$(dirname "$0")/.." && pwd)"Environment
eval "$(zoxide init bash)"addsalias cd=z)CDPATHexportWorkaround
Users can unset
CDPATHbefore running gstack, but sincegstack-update-checkruns automatically in skill preambles, there is no practical workaround without patching the scripts.