Summary
With runtime rotation enabled, mcodex resume hangs on a blank screen after printing the multi-auth status line, while the equivalent official codex resume command works normally.
Using CODEX_MULTI_AUTH_RUNTIME_ROTATION_PROXY=0 mcodex resume ... also works, but disables automatic runtime account rotation and therefore is not an acceptable permanent workaround.
The problem was diagnosed and locally fixed with OpenAI GPT-5.6-sol. The validated diagnosis is that resume and fork are interactive TUI entry points but are routed through the ephemeral shadow-home request path instead
of the canonical-home TUI helper path.
A second related problem was found: after an interrupted/nonzero Codex exit, the rotation helper can remain referenced after its graceful-shutdown timeout, preventing mcodex from returning to the shell.
Reproduction
-
Install the current stable package:
npm install -g codex-multi-auth
-
Add multiple accounts and enable runtime rotation.
-
Confirm that the session resumes through the official CLI:
codex resume <session-id>
This works normally.
-
Attempt the same resume through the wrapper:
mcodex resume <session-id>
-
The multi-auth status line appears, but the resumed TUI remains blank and never becomes usable.
-
Disable the runtime proxy for only that invocation:
CODEX_MULTI_AUTH_RUNTIME_ROTATION_PROXY=0 mcodex resume <session-id>
The session opens normally, confirming that the failure is specific to the runtime-rotation path.
-
After routing resume through the canonical-home helper locally, resume works. However, an interrupted/nonzero exit can leave the wrapper stuck after Codex prints its final “To continue this session...” message. The
shell prompt does not return.
Expected Behavior
mcodex resume [session-id] and mcodex fork [session-id] should behave like the equivalent official Codex TUI commands while retaining automatic account rotation.
After /exit, interruption, or another Codex termination, the wrapper should always return control to the shell within a bounded amount of time.
Actual Behavior
Two related failures occur:
resume/fork are classified as request commands and use an ephemeral shadow CODEX_HOME. The shadow SQLite state can be incomplete, causing resume to hang even though the session rollout file exists.
- If the detached rotation helper does not terminate during its two-second graceful shutdown window, the wrapper stops waiting but leaves the child process/streams referenced. The Node wrapper then remains alive
indefinitely.
Environment
codex --version: codex-cli 0.146.0
codex-multi-auth --version: 2.8.0
npm ls -g codex-multi-auth: codex-multi-auth@2.8.0
- Runtime rotation: enabled
- Accounts: 2
- Storage health: healthy
- OS: Pop!_OS 24.04 LTS
- Kernel: Linux 7.0.11-76070011-generic x86_64
- Node.js:
v24.17.0
- npm:
12.0.0
Diagnostic Evidence
codex-multi-auth check reported both accounts as signed in and available.
codex-multi-auth rotation status reported:
- runtime rotation proxy enabled
- stored setting enabled
- no environment override
codex resume <session-id> worked.
mcodex resume <session-id> hung.
CODEX_MULTI_AUTH_RUNTIME_ROTATION_PROXY=0 mcodex resume <session-id> worked.
- The normal
sessions directory was correctly symlinked into the generated shadow homes.
- The canonical
state_5.sqlite contained 257 indexed threads and the requested thread.
- The two shadow databases created by the failed launches contained only 126 and 128 threads and did not contain the requested thread.
- No
~/.codex/multi-auth/logs/codex-plugin/ directory was created.
- After the exit hang, Bash showed the wrapper as a stopped job when
Ctrl+Z was used.
Account emails, account IDs, OAuth data, and the real session UUID have intentionally been omitted.
Diagnosis
In scripts/codex.js, isCodexInteractiveTuiCommand only recognizes an invocation with no forwarded command:
function isCodexInteractiveTuiCommand(rawArgs) {
return findForwardedCommand(rawArgs) === null;
}
However, resume and fork are also interactive TUI entry points. They are included in requestCommands, so they take the ephemeral proxy/shadow-home path.
Treating resume and fork as interactive TUI commands makes them use the canonical-home app-helper path already used by normal mcodex.
This local patch fixed resume while keeping runtime account rotation enabled:
function isCodexInteractiveTuiCommand(rawArgs) {
- return findForwardedCommand(rawArgs) === null;
+ const command = findForwardedCommand(rawArgs);
+ return (
+ command === null ||
+ command.command === "resume" ||
+ command.command === "fork"
+ );
}
The helper shutdown code also has an unbounded process-lifetime failure. waitForRuntimeRotationAppHelperExit stops waiting after two seconds, but stopRuntimeRotationAppHelper can leave the helper and its streams
referenced if it has not actually exited.
This additional local patch fixed the shell-return problem:
-function stopRuntimeRotationAppHelper(helper) {
+async function stopRuntimeRotationAppHelper(helper) {
if (!helper || helper.killed) {
- return Promise.resolve();
+ return;
}
try {
helper.kill("SIGTERM");
} catch {
- return Promise.resolve();
+ return;
+ }
+ await waitForRuntimeRotationAppHelperExit(helper);
+ if (helper.exitCode === null && helper.signalCode === null) {
+ try {
+ helper.kill("SIGKILL");
+ } catch {
+ // Best-effort force-stop after the graceful shutdown timeout.
+ }
}
- return waitForRuntimeRotationAppHelperExit(helper);
+ helper.stdout?.destroy();
+ helper.stderr?.destroy();
+ helper.unref();
}
Both patches were applied to the installed codex-multi-auth@2.8.0 wrapper, passed node --check, and were validated through a real terminal:
mcodex resume <session-id> opened successfully with runtime rotation enabled.
/exit returned to the Bash prompt normally.
- No
Ctrl+Z workaround was required.
AI-Assisted Diagnosis Disclosure
This issue was investigated, diagnosed, patched, and interactively validated with OpenAI GPT-5.6-sol. GPT-5.6-sol inspected the installed package source and the generated shadow-home SQLite metadata, identified both code
paths above, produced the local patches, and guided the terminal validation. The user executed the real interactive Codex tests.
Compliance Confirmation
Summary
With runtime rotation enabled,
mcodex resumehangs on a blank screen after printing the multi-auth status line, while the equivalent officialcodex resumecommand works normally.Using
CODEX_MULTI_AUTH_RUNTIME_ROTATION_PROXY=0 mcodex resume ...also works, but disables automatic runtime account rotation and therefore is not an acceptable permanent workaround.The problem was diagnosed and locally fixed with OpenAI GPT-5.6-sol. The validated diagnosis is that
resumeandforkare interactive TUI entry points but are routed through the ephemeral shadow-home request path insteadof the canonical-home TUI helper path.
A second related problem was found: after an interrupted/nonzero Codex exit, the rotation helper can remain referenced after its graceful-shutdown timeout, preventing
mcodexfrom returning to the shell.Reproduction
Install the current stable package:
Add multiple accounts and enable runtime rotation.
Confirm that the session resumes through the official CLI:
This works normally.
Attempt the same resume through the wrapper:
The multi-auth status line appears, but the resumed TUI remains blank and never becomes usable.
Disable the runtime proxy for only that invocation:
The session opens normally, confirming that the failure is specific to the runtime-rotation path.
After routing
resumethrough the canonical-home helper locally, resume works. However, an interrupted/nonzero exit can leave the wrapper stuck after Codex prints its final “To continue this session...” message. Theshell prompt does not return.
Expected Behavior
mcodex resume [session-id]andmcodex fork [session-id]should behave like the equivalent official Codex TUI commands while retaining automatic account rotation.After
/exit, interruption, or another Codex termination, the wrapper should always return control to the shell within a bounded amount of time.Actual Behavior
Two related failures occur:
resume/forkare classified as request commands and use an ephemeral shadowCODEX_HOME. The shadow SQLite state can be incomplete, causing resume to hang even though the session rollout file exists.indefinitely.
Environment
codex --version:codex-cli 0.146.0codex-multi-auth --version:2.8.0npm ls -g codex-multi-auth:codex-multi-auth@2.8.0v24.17.012.0.0Diagnostic Evidence
codex-multi-auth checkreported both accounts as signed in and available.codex-multi-auth rotation statusreported:codex resume <session-id>worked.mcodex resume <session-id>hung.CODEX_MULTI_AUTH_RUNTIME_ROTATION_PROXY=0 mcodex resume <session-id>worked.sessionsdirectory was correctly symlinked into the generated shadow homes.state_5.sqlitecontained 257 indexed threads and the requested thread.~/.codex/multi-auth/logs/codex-plugin/directory was created.Ctrl+Zwas used.Account emails, account IDs, OAuth data, and the real session UUID have intentionally been omitted.
Diagnosis
In
scripts/codex.js,isCodexInteractiveTuiCommandonly recognizes an invocation with no forwarded command:However,
resumeandforkare also interactive TUI entry points. They are included inrequestCommands, so they take the ephemeral proxy/shadow-home path.Treating
resumeandforkas interactive TUI commands makes them use the canonical-home app-helper path already used by normalmcodex.This local patch fixed resume while keeping runtime account rotation enabled:
function isCodexInteractiveTuiCommand(rawArgs) { - return findForwardedCommand(rawArgs) === null; + const command = findForwardedCommand(rawArgs); + return ( + command === null || + command.command === "resume" || + command.command === "fork" + ); }The helper shutdown code also has an unbounded process-lifetime failure.
waitForRuntimeRotationAppHelperExitstops waiting after two seconds, butstopRuntimeRotationAppHelpercan leave the helper and its streamsreferenced if it has not actually exited.
This additional local patch fixed the shell-return problem:
Both patches were applied to the installed
codex-multi-auth@2.8.0wrapper, passednode --check, and were validated through a real terminal:mcodex resume <session-id>opened successfully with runtime rotation enabled./exitreturned to the Bash prompt normally.Ctrl+Zworkaround was required.AI-Assisted Diagnosis Disclosure
This issue was investigated, diagnosed, patched, and interactively validated with OpenAI GPT-5.6-sol. GPT-5.6-sol inspected the installed package source and the generated shadow-home SQLite metadata, identified both code
paths above, produced the local patches, and guided the terminal validation. The user executed the real interactive Codex tests.
Compliance Confirmation