Skip to content

npm update leaves app-server on old version, but daemon update/restart refuse recovery #46468

Open

Description

@sun-binwen

npm update leaves app-server on old version, but daemon update/restart refuse recovery

What version of Codex CLI is running?

codex-cli 0.155.0

The still-running background app-server reported 0.154.0.

Component

Codex CLI / app-server daemon / npm updater

Platform

  • WSL2: Linux 6.18.33.2-microsoft-standard-WSL2 x86_64
  • Ubuntu 26.04 LTS
  • Node.js v22.23.1
  • npm 10.9.8
  • npm package: @openai/codex@0.155.0

What issue are you seeing?

This is the second time an npm update has left the running app-server on the previous Codex version with no supported recovery path.

The CLI, npm package, and native binary on disk were already 0.155.0, but the app-server process had started immediately before the npm update and remained 0.154.0:

{
  "status": "running",
  "managedCodexPath": "/home/sbw/.codex/packages/standalone/current/codex",
  "managedCodexVersion": null,
  "socketPath": "/home/sbw/.codex/app-server-control/app-server-control.sock",
  "cliVersion": "0.155.0",
  "appServerVersion": "0.154.0"
}

At that time there was no standalone installation at the reported managedCodexPath. The visible ~/.local/bin/codex was a wrapper that loaded NVM and executed the npm-installed CLI:

~/.nvm/versions/node/v22.23.1/bin/codex
  -> ../lib/node_modules/@openai/codex/bin/codex.js

The running daemon was from that npm installation:

node ~/.nvm/versions/node/v22.23.1/bin/codex \
  -c features.code_mode_host=true app-server --listen unix://

The process began at 04:05:49, while the npm codex symlink was updated at 04:06. This is consistent with npm replacing the on-disk package while leaving the already-running 0.154.0 daemon alive.

The warning suggested running:

codex app-server daemon update

but that command refused:

{
  "status": "unsupported",
  "managedCodexPath": "/home/sbw/.codex/packages/standalone/current/codex",
  "installedVersion": null,
  "runningVersion": "0.154.0",
  "message": "This command requires a CLI-managed daemon and a stable latest-channel standalone install; update this installation with its owning installer."
}

The obvious fallback also refused:

$ codex app-server daemon restart
Error: app server is running but is not managed by codex app-server daemon

So the CLI detects the mismatch and recommends a command that cannot work for the npm installation, while the restart command also refuses to recover it.

Steps to reproduce

  1. Install Codex globally through npm and start the shared app-server daemon from that installation.
  2. Keep a client connected to the daemon.
  3. Upgrade @openai/codex globally from 0.154.0 to 0.155.0 without first stopping the daemon.
  4. Run codex app-server daemon version and observe CLI 0.155.0 with app-server 0.154.0.
  5. Run codex app-server daemon update and codex app-server daemon restart.
  6. Observe that update reports unsupported and restart reports that the running server is not managed.

Expected behavior

At least one supported recovery path should work:

  • npm updates should stop/restart a daemon launched from the package being replaced; or
  • the newer CLI should be able to restart a reachable older daemon from the same npm installation; or
  • the warning should provide an npm-specific command that actually reconciles the running daemon; or
  • doctor / daemon version should explain that the process predates the package update and offer a safe takeover flow.

It is also misleading for an npm-managed invocation to report a nonexistent standalone path as managedCodexPath.

Actual recovery required

Normal TERM did not make the old daemon exit within 10 seconds while clients were connected. Recovery required:

  1. Install the official standalone 0.155.0 distribution.
  2. Replace the visible CLI path with the standalone symlink.
  3. Force-kill the old npm daemon process group.
  4. Remove the unowned control socket.
  5. Start a new managed standalone daemon.

After that, the daemon reported:

{
  "status": "running",
  "managedCodexVersion": "0.155.0",
  "cliVersion": "0.155.0",
  "appServerVersion": "0.155.0"
}

Related issue

Possibly related to #44037 because both end in a reachable but “unmanaged” daemon. However, #44037 attributes lost management to WSL2 clock changes and PID start-time validation. This case was tied to an npm package update leaving the old process alive, with no standalone installation or management metadata present.

Activity

  1. added
    bugSomething isn't working
    CLIIssues related to the Codex CLI
    app-serverIssues involving app server protocol or interfaces
    on Sep 18, 2026
  2. sun-binwen commented on Sep 18, 2026

    @sun-binwen
    Author

    CLI /feedback was also submitted for this report (without session logs).

    Feedback thread ID: 01a0b5ca-57e3-7fa2-8df5-af3f08be2034

  3. 84dnnvbdvp-debug commented on Sep 18, 2026

    @84dnnvbdvp-debug

    Exact rust-v0.155.0 source makes this look like a real lifecycle gap rather than an updater race that merely needs a longer wait.

    Two independent guards leave the reported npm-owned daemon with no supported transition:

    • app-server-daemon/src/manual_update.rs returns Unsupported unless the selected binary is a stable managed standalone release, and it also rejects a reachable socket when running_backend_instance(...) cannot prove daemon ownership.
    • app-server-daemon/src/lib.rs::restart() separately rejects the same state when the socket probe succeeds but running_backend(...) is None, with the exact app server is running but is not managed... error.

    There is also a diagnostic artifact in 0.155.0: managed_install::managed_codex_bin() synthesizes $CODEX_HOME/packages/standalone/current/codex on Unix as its fallback even when no managed install exists. LifecycleOutput then exposes that as managedCodexPath, so that field is not evidence that the running process came from—or can be recovered through—that path. That matches the report's nonexistent path.

    Current main has moved toward a dedicated daemon-owned package and explicit legacy migration, but the new migration still deliberately returns unsupported when the control socket is reachable and the process is not recognized as a managed backend. So as far as public source shows, the npm-started/unowned case still needs an explicit ownership-aware recovery contract; simply widening restart to kill any reachable process would weaken an important safety boundary.

    I would pin the repair with an installer-ownership regression rather than only a version-mismatch regression:

    1. Start the shared daemon from npm package A; keep a client/subscription open.
    2. Replace npm package A with B without daemon metadata that makes it CLI-managed.
    3. From B, require daemon version to distinguish running daemon provenance/ownership from the prospective managed destination (do not report a nonexistent managed path as if it owned the process).
    4. The warning must offer a recovery that is actually valid for that provenance. If Codex supports takeover, require positive identity/provenance checks before graceful handoff and preserve a negative control where an unrelated process owns the same reachable socket/state so it is never killed or adopted.
    5. After successful reconciliation, assert one current daemon, no stale control socket/PID state, and preserved/recovered active-thread state according to the documented restart contract.

    That keeps the existing fail-closed ownership rule while fixing the dead end: mismatch detection, remediation advice, and the command that performs remediation need to agree on who owns the running process.

  4. leynos commented on Sep 20, 2026

    @leynos

    I'm experiencing the same problem. Is there a work-around?

  5. Nurshot commented on Sep 20, 2026

    @Nurshot

    same problem

  6. baskan commented on Sep 21, 2026

    @baskan

    any workarounds?

  7. arsharaf commented on Sep 21, 2026

    @arsharaf

    same issue

  8. ysys143 commented on Sep 30, 2026

    @ysys143

    Additional reproduction on macOS: stale app-server hides newly available models

    I reproduced the same CLI/app-server version-skew and recovery failure on macOS, with a visible model-catalog impact.

    Environment

    • Platform: macOS
    • CLI version: 0.159.2
    • Running app-server version before recovery: 0.153.4
    • Authentication: ChatGPT account

    Observed behavior

    Before recovery, the local app-server model catalog did not include gpt-6.1-sol, gpt-6-sol, and gpt-6-luna, although a fresh catalog request for client version 0.159.2 included them.

    $ codex app-server daemon restart
    Error: app server is running but is not managed by codex app-server daemon
    
    $ codex app-server daemon start
    {"status":"alreadyRunning","managedCodexVersion":null,"cliVersion":"0.159.2","appServerVersion":"0.153.4"}
    

    daemon bootstrap also reported that the existing app-server was not daemon-managed. Manual termination of the stale processes was required. Afterward, the daemon recreated the app-server correctly at 0.159.2, and the current models became available.

    Expected behavior

    After a CLI update, the daemon should replace or adopt an incompatible app-server. The model catalog should reflect the current CLI/server version. If automatic recovery is impossible, a supported command should identify the owner and recover the state.

    Actual behavior

    An older app-server remained active and served a stale model catalog. The CLI detected the mismatch, but daemon restart and daemon start could not repair it.

    Impact

    The model picker made newly available models appear unavailable, while the daemon reported that an app-server was already running. Manual process inspection and termination were required.

  9. shakystar commented on Oct 9, 2026

    @shakystar

    Additional observation on native Windows using the npm-installed CLI: the version mismatch recurs after following the official update prompt in the interactive Codex CLI. The user-facing update flow updates the npm package, but leaves the managed background server on an older version.

    Verified on October 9, 2026:

    • npm.cmd list -g @openai/codex --depth=0: @openai/codex@0.162.0
    • codex.cmd --version: codex-cli 0.162.0
    • codex.cmd app-server daemon version returned the following fields (local paths omitted):
    {
      "status": "running",
      "backend": "pid",
      "managedCodexVersion": "0.160.0",
      "cliVersion": "0.162.0",
      "appServerVersion": "0.160.0"
    }

    Process inspection also confirmed that the running managed app-server executable comes from the separate .codex/packages/app-server-daemon/releases/ package, while the CLI comes from the global npm installation.

    The important UX detail is that this follows the update action offered by Codex itself, rather than a separately chosen manual upgrade procedure. This mismatch has occurred repeatedly across updates on this machine.

    Scope of this confirmation: it confirms the update/version-skew part of this issue. I have not attempted daemon update/restart for this latest occurrence, so I am not claiming to reproduce the original report's unsupported or unmanaged-daemon recovery failures, or that the version difference alone proves the cause of every CLI symptom.

    Expected behavior: the official update flow should account for the managed server as well as the npm CLI, safely coordinate any necessary server update/restart, and verify the effective running version. If it cannot do that during active work, it should clearly report that the server still needs updating and provide the supported next step.

    Related: #37536 describes an older app-server continuing to serve a newly updated CLI and retaining old behavior.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    CLIIssues related to the Codex CLIapp-serverIssues involving app server protocol or interfacesbugSomething isn't working

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions