You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
st2 driver codex's controlled launch always passes --listen (run_controlled_owned → the --listen boundary at src/codex_app_server.rs:1440). On that path the Codex app-server refuses to start when $CODEX_HOME/app-server-control is a symlink, even when the symlink target is a real, existing directory:
Error: socket directory path exists and is not a directory: <CODEX_HOME>/app-server-control
The wrapper surfaces this as a failed launch; the error text lands in app-server.log.
Fleet evidence
~/.codex/app-server-control is a symlink on at least one machine in this fleet — it points at ~/.codex-schickling-j/app-server-control, part of a per-account ~/.codex layout in which nearly every entry is symlinked. On that host, controlled Codex launch cannot start at all.
Reproduction
T=$(mktemp -d "$HOME/probe.XXXX"); mkdir -p "$T/real-control""$T/home""$T/sock"printf'model = "gpt-5.6-sol"\n'>"$T/home/config.toml"# A — symlinked control dir
ln -s "$T/real-control""$T/home/app-server-control"
CODEX_HOME="$T/home" timeout 10 codex app-server --listen "unix://$T/sock/a.sock"</dev/null
# -> rc=1, "socket directory path exists and is not a directory: .../app-server-control"# B — real control dir (control case)
rm "$T/home/app-server-control"; mkdir -p "$T/home/app-server-control"
CODEX_HOME="$T/home" timeout 10 codex app-server --listen "unix://$T/sock/b.sock"</dev/null
# -> rc=124 (still running = started successfully)
Scope, established rather than assumed
Requires --listen. Bare codex app-server starts cleanly with the symlink in place, in both configurations. This is why an initial probe failed to reproduce it.
Not the socket path. The --listen target above is inside a real directory and it still refuses.
Not CODEX_HOME itself. In the reproduction CODEX_HOME is a real directory; only its app-server-control child is a symlink, and that alone is sufficient.
The symlink target exists and is a real directory in every failing case, so this looks like an lstat-vs-stat check upstream rather than a broken link.
Options
Upstream-facing: the check appears over-strict — a symlink resolving to a directory is a directory for every purpose the socket path needs.
st2-facing, if a workaround is wanted before upstream changes: the controlled launch could resolve $CODEX_HOME/app-server-control before handing it over, or doctor could detect the symlink and report it as a known-fault precondition rather than letting the launch fail with a message that appears only in app-server.log.
No preference asserted here — the surfacing question in particular is a maintainer call.
Acceptance
The failure mode is either fixed upstream, worked around in the controlled launch, or reported as a precondition by doctor rather than only in app-server.log.
Problem
st2 driver codex's controlled launch always passes--listen(run_controlled_owned→ the--listenboundary atsrc/codex_app_server.rs:1440). On that path the Codex app-server refuses to start when$CODEX_HOME/app-server-controlis a symlink, even when the symlink target is a real, existing directory:The wrapper surfaces this as a failed launch; the error text lands in
app-server.log.Fleet evidence
~/.codex/app-server-controlis a symlink on at least one machine in this fleet — it points at~/.codex-schickling-j/app-server-control, part of a per-account~/.codexlayout in which nearly every entry is symlinked. On that host, controlled Codex launch cannot start at all.Reproduction
Scope, established rather than assumed
--listen. Barecodex app-serverstarts cleanly with the symlink in place, in both configurations. This is why an initial probe failed to reproduce it.--listentarget above is inside a real directory and it still refuses.CODEX_HOMEitself. In the reproductionCODEX_HOMEis a real directory; only itsapp-server-controlchild is a symlink, and that alone is sufficient.SUPPORTED_CODEX_CLI_VERSIONS— and on 0.147.0. Untested on 0.145.0. This is therefore a live failure against a supported version today, and is independent of st2 refuses the locally installed codex-cli, and the version pin is now behind by one release #267 / Admit codex-cli 0.147.0 after repeating the pin's policy checks #272.lstat-vs-statcheck upstream rather than a broken link.Options
Upstream-facing: the check appears over-strict — a symlink resolving to a directory is a directory for every purpose the socket path needs.
st2-facing, if a workaround is wanted before upstream changes: the controlled launch could resolve
$CODEX_HOME/app-server-controlbefore handing it over, ordoctorcould detect the symlink and report it as a known-fault precondition rather than letting the launch fail with a message that appears only inapp-server.log.No preference asserted here — the surfacing question in particular is a maintainer call.
Acceptance
doctorrather than only inapp-server.log.