Shell installer: literal $ in CODEX_INSTALL_DIR corrupts generated profile PATH

Open Beginner friendly
#60,494 1 comment 0 reactions 0 assignees View on GitHub

Maintainers usually reply within 1 day

Nobody has claimed this yet.

Assessment

Difficulty
2/5
Estimated time
1-3 hours
Newbie friendliness
72/100
Issue type
Bug
Clarity
Clearly specified
Activity status
Active
Tech stack
shell
Domain
cli

Research direction

The bug is in add_to_path() in scripts/install/install.sh, where the PATH line is built from BIN_DIR inside a double-quoted string. Reproduce with the standalone snippet in the issue, then change only the literal BIN_DIR part so it is shell-quoted while the existing $PATH still expands when the profile is sourced. Done when a directory containing a literal dollar sign resolves codex in a freshly sourced shell, and the test fixture covers that case.

Written by the indexing model from the issue text.

Description

bug CLI
What issue are you seeing?

The standalone shell installer can complete successfully but leave Codex unavailable in a new shell when CODEX_INSTALL_DIR is an absolute path containing a literal dollar sign followed by variable-name characters.

The installed executable exists and is runnable by its full path. The generated shell-profile PATH entry reinterprets part of the literal directory name as an environment-variable expansion, so normal command lookup cannot find it.

Affected source: main 4dcd8df891ad38ed7d4ea59c44b817c293ffc0e2, also verified on 1885417cd45a8da5bfdeb7864a5380a7481d48f2.
Platform tested: Linux x86_64, /bin/sh. The full installer was also exercised with the repository's local download/package fixture, without network calls; the fixture reports package version 0.142.5 (not an assertion about the currently released Codex version).

What steps can reproduce the bug?

This minimal standalone reproduction exercises the exact PATH-line construction used in add_to_path(), followed by sourcing that line in a new POSIX shell. It makes no changes to your real home directory:

set -eu
root="$(mktemp -d)"
trap 'rm -rf "$root"' EXIT

# The dollar sign is literal and part of this absolute directory name.
BIN_DIR="$root/literal\$CODEX_TEST_UNSET/install-bin"
mkdir -p "$BIN_DIR"
printf '#!/bin/sh\necho codex-fixture\n' > "$BIN_DIR/codex"
chmod +x "$BIN_DIR/codex"

# The expression from scripts/install/install.sh:add_to_path().
path_line="export PATH=\"$BIN_DIR:\$PATH\""
printf '%s\n' "$path_line" > "$root/profile"
printf 'generated profile: '
cat "$root/profile"

# A new shell reads that generated profile without this variable set.
env -u CODEX_TEST_UNSET /bin/sh -c '
    . "$1"
    command -v codex || echo NOT_FOUND
    test -x "$2/codex" && echo ACTUAL_BINARY_EXISTS
' sh "$root/profile" "$BIN_DIR"

Actual output (temporary prefix abbreviated):

generated profile: export PATH="/tmp/.../literal$CODEX_TEST_UNSET/install-bin:$PATH"
NOT_FOUND
ACTUAL_BINARY_EXISTS

In a complete unchanged-installer fixture, an ordinary absolute install path succeeded and resolved from a fresh shell, while the same absolute path with literal $CODEX_TEST_UNSET installed successfully but failed fresh-shell lookup with exit 127. The original executable was present in both cases.

What is the expected behavior?

A generated profile entry should preserve CODEX_INSTALL_DIR exactly as a literal filesystem path. After installation and sourcing the supported profile, command -v codex should locate the installed binary regardless of literal dollar signs in the directory.

Additional information

Root cause: scripts/install/install.sh:add_to_path() constructs:

path_line="export PATH=\"$BIN_DIR:\$PATH\""

The installer substitutes BIN_DIR without escaping shell-significant characters inside a double-quoted assignment. This text is later written to the selected profile. When sourced, the shell expands the apparent variable inside what should have been the literal directory.

Suggested fix: POSIX-shell-quote the literal BIN_DIR component in the generated profile, while intentionally allowing the existing PATH to expand at source time. Test with a directory containing a dollar sign (and ideally quote/backslash characters), and assert that the newly sourced profile resolves the actual binary.

Related but distinct: #51538 covers relative CODEX_HOME/CODEX_INSTALL_DIR paths and cwd-dependent links. This bug uses an absolute path and is caused by shell interpolation within the generated profile. I searched issues/PRs for the literal-dollar/path-escaping case and did not find an existing equivalent report.

Limits: Confirmed on Linux /bin/sh; actual macOS shells and release downloads were not exercised. No claim of arbitrary command execution is made here; the demonstrated failure is incorrect PATH generation and inability to locate the installed command.

Dominant language
Rust
Stars
133k
Forks
21.1k
Avg merge
1m
Merged PRs (30d)
995

Getting set up

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

More from openai/codex

All issues in openai/codex

Similar issues

More Rust issues

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.