Skip to content

fix: CDPATH breaks all bin/ scripts — cd stdout corrupts path variables#918

Open
Hybirdss wants to merge 1 commit intogarrytan:mainfrom
Hybirdss:fix/cdpath-breaks-bin-scripts
Open

fix: CDPATH breaks all bin/ scripts — cd stdout corrupts path variables#918
Hybirdss wants to merge 1 commit intogarrytan:mainfrom
Hybirdss:fix/cdpath-breaks-bin-scripts

Conversation

@Hybirdss
Copy link
Copy Markdown

@Hybirdss Hybirdss commented Apr 8, 2026

Summary

When CDPATH is set (common with zsh users, zoxide, custom .zshrc navigation), cd prints the resolved path to stdout if it resolves through CDPATH. This doubles the output of $(cd ... && pwd), corrupting GSTACK_DIR, SCRIPT_DIR, and every path derived from them.

Most visible impact: gstack-update-check silently exits — VERSION_FILE becomes a two-line string, [ -f "$VERSION_FILE" ] fails, and upgrade detection never runs. Users with CDPATH set are permanently stuck on their installed version.

Fix: redirect cd stdout with >/dev/null 2>&1 in all path-resolution patterns. This is the standard POSIX-safe idiom for cd inside command substitution.

18 files, 21 call sites:

bin/dev-setup                  bin/gstack-relink
bin/dev-teardown               bin/gstack-repo-mode
bin/gstack-community-dashboard bin/gstack-review-log
bin/gstack-extension           bin/gstack-review-read
bin/gstack-learnings-log       bin/gstack-specialist-stats
bin/gstack-learnings-search    bin/gstack-telemetry-log
bin/gstack-platform-detect     bin/gstack-telemetry-sync
bin/gstack-timeline-log        bin/gstack-timeline-read
bin/gstack-uninstall           bin/gstack-update-check

Before (broken):

GSTACK_DIR="$(cd "$(dirname "$0")/.." && pwd)"
# With CDPATH=".:/home/user" → GSTACK_DIR="/path\n/path" (two lines)

After (fixed):

GSTACK_DIR="$(cd "$(dirname "$0")/.." >/dev/null 2>&1 && pwd)"
# With any CDPATH → GSTACK_DIR="/path" (one line, correct)

Reproduction

export CDPATH=".:/home/user:/home/user/dev"
~/.claude/skills/gstack/bin/gstack-update-check --force
# No output — silently exits, never checks remote VERSION

Scope

This PR fixes bin/ scripts only. The same pattern exists in setup, scripts/build-app.sh, scripts/app/gstack-browser, browse/scripts/build-node-server.sh, gstack-upgrade/migrations/v0.15.2.0.sh, and supabase/verify-rls.sh — flagging as a follow-up to keep this PR focused.

Test plan

  • CDPATH=".:/tmp" bash bin/gstack-update-check --force — no longer silently exits
  • Verified $(cd path >/dev/null 2>&1 && pwd) returns single line with CDPATH set
  • Verified original pattern returns two lines with CDPATH set (confirmed the bug)
  • bun test passes (6 pre-existing failures, 0 new — golden file + version mismatch)

Closes #824

Generated with Claude Code

…upting variables

When CDPATH is set (common with zsh users, zoxide, custom navigation),
`cd` prints the resolved path to stdout if it resolves through CDPATH.
This doubles the output of `$(cd ... && pwd)`, corrupting GSTACK_DIR,
SCRIPT_DIR, and every path derived from them.

Most visible impact: gstack-update-check silently exits because
VERSION_FILE becomes a two-line string, `[ -f "$VERSION_FILE" ]` fails,
and upgrade detection never runs.

Fix: redirect cd stdout with `>/dev/null 2>&1` in all 18 bin/ scripts
(21 call sites). This is the standard POSIX-safe pattern for cd inside
command substitution.

Closes garrytan#824
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.

CDPATH breaks all bin/ scripts — cd outputs path to stdout, corrupting variable assignments

1 participant