Hacktoberfest 2026: the issues maintainers tagged for October, open and beginner-friendly. Browse Hacktoberfest issues

Shell installer: relative CODEX_HOME breaks package links and relative CODEX_INSTALL_DIR writes a cwd-dependent PATH

Open Beginner friendly
#51,538 0 comments 0 reactions 0 assignees View on GitHub

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

bug CLI
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

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.