Shell installer: relative CODEX_HOME breaks package links and relative CODEX_INSTALL_DIR writes a cwd-dependent PATH
Maintainers usually reply within 1 day
Nobody has claimed this yet.
Assessment
- Difficulty
- 2/5
- Estimated time
- Under an hour
- Newbie friendliness
- 85/100
- Issue type
- Bug
- Clarity
- Clearly specified
- Activity status
- Active
- Tech stack
- bash
- Domain
- cli
Research direction
The shell installer writes relative paths as symlink targets and profile entries when CODEX_HOME or CODEX_INSTALL_DIR are relative. Start from the install script exercised by scripts/install/test_install_sh.py, locate where CODEX_HOME_DIR and BIN_DIR are used to construct the current symlink and PATH entry, and convert them to absolute paths. Run the installer test suite to confirm the fix.
Written by the indexing model from the issue text.
Description
What issue are you seeing?
The shell installer generates a broken current symlink when CODEX_HOME is relative. The package is unpacked successfully, but a normal install exits 127 when it verifies the visible command. In daemon-only mode installation can exit 0 while current/bin/codex remains unusable.
A related path problem occurs when CODEX_INSTALL_DIR is relative: the visible link works from the installation directory, but the generated profile PATH entry is relative, so codex stops resolving after the working directory changes.
Checked main at ac9b5b8380517ded445b09dd3196d8d9e2ba3c59. Evidence below uses the existing local installer fixture on Linux, with its macOS mock; this is not a test on a real macOS host.
What steps can reproduce the bug?
Save the following script and run python installer-relative-home-repro.py /path/to/codex-checkout. It uses the checkout's existing package/download fixture, requires no network, and confines profile writes to a temporary directory.
#!/usr/bin/env python3
"""Local installer reproduction; uses Linux with the fixture's macOS mock.
Usage: python installer-relative-home-repro.py /path/to/codex-checkout
All downloads and profile writes are confined to the existing local fixture.
"""
import importlib.util
from pathlib import Path
import subprocess
import sys
import tempfile
from unittest.mock import patch
checkout = Path(sys.argv[1]).resolve()
fixture_path = checkout / "scripts/install/test_install_sh.py"
spec = importlib.util.spec_from_file_location("installer_fixture", fixture_path)
fixture = importlib.util.module_from_spec(spec)
spec.loader.exec_module(fixture)
original_run = subprocess.run
with tempfile.TemporaryDirectory(prefix="codex installer repro ") as temporary:
root = Path(temporary).resolve()
archive, checksum, metadata = fixture.create_package_release(root)
def run_with_relative_home(args, **kwargs):
if len(args) > 1 and Path(args[1]) == fixture.INSTALL_SCRIPT:
kwargs["env"] = {**kwargs["env"], "CODEX_HOME": "codex-home"}
kwargs["cwd"] = root
return original_run(args, **kwargs)
with patch.object(fixture.subprocess, "run", side_effect=run_with_relative_home):
result, _ = fixture.run_installer_in(
root,
fixture.VERSION,
metadata_json=metadata,
archive_path=archive,
checksum_path=checksum,
force_macos=True,
)
current = root / "codex-home/packages/standalone/current"
package = current.parent / "releases" / f"{fixture.VERSION}-aarch64-apple-darwin"
visible = root / "install-bin/codex"
print(f"installer_exit={result.returncode}")
print(f"installed_package_binary_exists={(package / 'bin/codex').exists()}")
print(f"current_target={current.readlink()}")
print(f"current_target_exists={current.exists()}")
print(f"visible_command_exists={visible.exists()}")
if result.stderr:
print(f"stderr={result.stderr.strip()}")
if visible.exists():
print(subprocess.check_output([str(visible), "--version"], text=True).strip())
On unmodified main:
installer_exit=127
installed_package_binary_exists=True
current_target=codex-home/packages/standalone/releases/0.142.5-aarch64-apple-darwin
current_target_exists=False
visible_command_exists=False
The final installer error is that the temporary install-bin/codex command is not found, despite the package binary existing. The fixture's version is 0.142.5; the defect is in the current install script's link construction rather than the CLI executable.
What is the expected behavior?
Resolve configured relative installation directories against the installer's initial working directory so package links and profile entries continue to work independently of later working directories.
Additional information
CODEX_HOME_DIR is used unchanged to derive STANDALONE_ROOT, then the relative release path is written as the target of current. A relative symlink target is resolved from the symlink's parent, not from the installer's working directory, producing the wrong path. BIN_DIR is likewise written as a relative path in the profile block.
A local candidate converts relative CODEX_HOME_DIR and BIN_DIR to absolute paths before deriving the other paths. The reproduction then exits 0, both links resolve, and the command prints codex-cli 0.142.5. Added fixture cases also cover daemon-only installation and sourcing the generated profile from a different directory; temporary paths include spaces. The complete installer suite passes 22 tests and 9 subtests, and sh -n and diff checks pass. Actual macOS and native release downloads were not tested.
Searched for relative CODEX_HOME/CODEX_INSTALL_DIR installer reports and did not find an equivalent issue. No external PR is requested, consistent with the contribution policy.
- Dominant language
- Rust
- Stars
- 128k
- Forks
- 20.1k
- Avg merge
- 1m
- Merged PRs (30d)
- 994
Getting set up
- No Dockerfile or Docker Compose file
- No pull request template
- Read the contributing guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
More from openai/codex
-
[macOS Desktop] New sidebar hover navigation accidentally switches sections while reaching a chatOpenapp bug
Difficulty 2/5 1-3 hours Newbie friendliness 70/100
Maintainers usually reply within 1 day
-
bug skills
Difficulty 2/5 1-3 hours Newbie friendliness 85/100
Maintainers usually reply within 1 day
-
bug CLI config
Difficulty 2/5 1-3 hours Newbie friendliness 78/100
Maintainers usually reply within 1 day
-
Shell installer: updating PATH replaces symlinked profiles and changes existing file permissionsOpenbug CLI
Difficulty 2/5 1-3 hours Newbie friendliness 85/100
Maintainers usually reply within 1 day
-
Git Bash on Windows: terminal enlarge/shrink breaks chat input and previous conversation scrollingOpenbug CLI TUI windows-os
Difficulty 2/5 1-3 hours Newbie friendliness 70/100
Maintainers usually reply within 1 day
Similar issues
-
Difficulty 2/5 1-3 hours Newbie friendliness 88/100
Maintainers usually reply within 4 days
-
Difficulty 2/5 1-3 hours Newbie friendliness 62/100
Maintainers usually reply within 1 day
-
Update dusk-bls12_381 to 0.16Possibly taken @HDauven claimed this today. Open
Difficulty 2/5 1-3 hours Newbie friendliness 72/100
-
`TcpListenerService` shares one `Extensions` store across all accepted connectionsPossibly taken A pull request linked to this issue is open or already merged. Open
Difficulty 2/5 1-3 hours Newbie friendliness 78/100
Maintainers usually reply within 1 day
-
Difficulty 2/5 1-3 hours Newbie friendliness 72/100
googlefonts/fontquant#43 ·