Skip to content

[Bug] Codex sign-in: Cancel cannot stop an in-progress login, and a failed attempt reports an acp-codex download error #828

Description

@tommy0103

Affected area

Agent runtime / ACP (Codex sign-in flow in the desktop app, executed by the embedded CLI daemon)

Installation method

Desktop release (analysis performed on a source checkout at commit 0a98b773)

Lody version or commit

0.93.3 (commit 0a98b773)

Operating system

macOS 15.7.4 arm64

What happened?

Two related defects in the Codex ("Sign in with ChatGPT") flow:

  1. The Cancel button cannot stop an in-progress sign-in. Start Codex sign-in; the browser opens the OpenAI device authorization page (auth.openai.com/codex/device). If that page never completes (e.g. device-code login is not enabled for the account, the tab is closed, or the network blocks the callback), clicking Cancel in the sign-in panel has no effect: the spawned codex login --device-auth process is not terminated and the panel keeps waiting until the daemon's built-in 285 s timeout fires.

  2. A failed sign-in attempt surfaces as an ACP runtime download error and a re-download prompt. If the managed Codex runtime is not yet installed (or its cache is stale), starting sign-in silently downloads the runtime first. When that download fails, the failure is reported as a sign-in error, and the agent settings dialog then shows the runtime as not installed / download failed with a "Download Agent / Retry download" prompt. One underlying failure (typically network) therefore produces two confusing errors, and the user is told to re-download acp-codex even though they only tried to log in.

What did you expect?

  • Cancel promptly terminates the login process and resets the sign-in UI.
  • Sign-in failures and runtime download failures are distinguished and reported separately; a runtime download triggered by sign-in shows progress and is cancellable.
  • A stale/mismatched runtime cache self-heals by reinstalling instead of dead-ending on an error that even "Retry download" cannot get past.

How can we reproduce it?

  1. Ensure the managed Codex runtime is not installed (fresh install, or remove <lody-data-dir>/agent-binaries/codex).
  2. In the desktop app, open the agent provider settings and start Codex "Sign in with ChatGPT".
  3. Let the browser open the OpenAI authorization page, but never complete it (close the tab, or use an account without device-code login enabled).
  4. Click Cancel in the sign-in panel. Observe: nothing happens; the flow only unwinds after the ~285 s daemon timeout.
  5. Separately, with the runtime not installed and the runtime download host unreachable, start sign-in. Observe: the sign-in fails, and the settings dialog then reports the runtime as missing / download failed and asks to re-download acp-codex.

How often does it happen?

Every time, under the conditions above (runtime not pre-installed and/or authorization page never completes).

Root cause analysis

Bug 1 — the cancel message is serialized behind the start message in the daemon's local control queue.

  • MessageProcessor.extractQueueKey assigns dedicated lanes only to session/* messages; all machine/* messages — including machine/acp-authenticate start and cancel — fall through to default and return null (apps/cli/src/lib/message-processor.ts:203-221).
  • ConcurrentQueue.enqueue maps a null key to a single shared '__default__' serial chain (apps/cli/src/lib/concurrent-queue.ts:24), so start and cancel execute strictly in order.
  • The start task occupies that lane until handler.handleMessage returns (apps/cli/src/lib/machine-runtime.ts:280,335), which awaits the spawned codex login --device-auth process exit or the 285 s timeout (apps/cli/src/agent/acp-authentication.ts:656-665 and :581-591).
  • AcpAuthenticationManager.cancel() itself is correctly implemented — sets the cancelled flag, aborts, SIGTERMs the process group, escalates to SIGKILL (acp-authentication.ts:700-716, :1123-1140) — but it is never dispatched while the start is still running. The renderer's cancel is also fire-and-forget with no optimistic UI update (packages/components/src/hooks/use-machine-acp-authentication.ts:47-58).
  • Suggested fix: assign machine/acp-authenticate messages a lane keyed by action (e.g. machine:acp-auth:<action>) so cancel/submit bypass the in-flight start; optionally update the UI optimistically on cancel. Small, localized change plus a queue test. (This also unblocks other machine/* control messages that currently stall behind a running login on the same lane.)

Bug 2 — the sign-in path silently owns the managed-runtime download, and a stale cache dead-ends.

  • authenticate() resolves the launch via resolveBuiltinAuthenticationProcessLaunch({ action: 'login' }) (acp-authentication.ts:599-604) → resolveManagedRuntimeForLaunch('codex') (apps/cli/src/agent/setting.ts:551) → resolveRuntimeForLaunch, which downloads on the spot when the runtime is missing (apps/cli/src/agent/managed-agent-runtime.ts:880-899).
  • Unlike the status-probe path (acp-authentication.ts:410-417), the login path passes neither signal nor onManagedRuntimeProgress: the UI shows no download progress, and neither cancel nor the 285 s timeout can interrupt the download (interruption is only checked after launch resolution, :608-609).
  • A download failure throws ManagedRuntimeError("Failed to install managed runtime codex: …") (managed-agent-runtime.ts:990-998), which the authenticate() catch reports as the sign-in error (acp-authentication.ts:680-685). The settings dialog's runtime status check then reports not-installed and prompts to download/retry — the "login failed, now re-download acp-codex" sequence.
  • Compounding issue: when a cached install's metadata no longer matches the pinned manifest (archive sha256/size/cmd), readCurrentInstallation throws (managed-agent-runtime.ts:790-799) instead of treating the cache as absent; because ensureCurrentRuntime performs the same check before downloading (:957), the dialog's "Retry download" fails again — only manually deleting agent-binaries/codex recovers.
  • Suggested fixes: (a) pass signal and an onManagedRuntimeProgress callback on the login path and surface download progress in the sign-in UI; (b) downgrade a metadata mismatch to "clean and reinstall" instead of throwing, so retry actually works.

Both fixes are small and localized (tens of lines each plus tests): Bug 1 is a queue-key change in message-processor.ts; Bug 2 is option plumbing in acp-authentication.ts plus a fallback branch in managed-agent-runtime.ts.

Relevant log output

# No crash log; the daemon stays blocked in the authenticate call until its 285 s timeout:
# "ChatGPT authentication timed out. Please try again."

Before submitting

  • I searched the existing issues and did not find a duplicate.
  • This report concerns an open-source component in this repository, not a hosted service, Web or mobile app, account, or billing issue.
  • This is not a security vulnerability; security reports follow the repository's security policy.
  • I removed credentials, private source, conversations, prompts, personal data, and other sensitive information.

Activity

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

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions