{"record":{"id":"424f4a9b5dfa1da3","repo":"stablyai/orca","slug":"codex-cli-does-not-support-the-app-server-subcomma","errorCode":null,"errorMessage":"codex CLI does not support the app-server subcommand: ${stderrTail.trim().slice(0, 400)}","messagePattern":"codex CLI does not support the app-server subcommand: (.+?)","errorType":"exception","errorClass":"CodexAppServerUnsupportedError","httpStatus":null,"severity":"warning","filePath":"src/main/codex/codex-app-server-session.ts","lineNumber":294,"sourceCode":"  try {\n    const session = async (): Promise<T> => {\n      await requestRpc('initialize', {\n        clientInfo: { name: 'orca_desktop', title: 'Orca', version: '0.0.0' }\n      })\n      notify('initialized')\n      return body({ request: requestRpc, notify })\n    }\n    // Why: the timeout owns the whole callback, including time between RPCs;\n    // killing the child alone cannot settle a callback awaiting unrelated work.\n    return await Promise.race([session(), deadlinePromise])\n  } catch (error) {\n    if (\n      error instanceof Error &&\n      !(error instanceof CodexAppServerUnsupportedError) &&\n      !(error instanceof CodexAppServerTimeoutError) &&\n      stderrIndicatesMissingAppServer(stderrTail)\n    ) {\n      throw new CodexAppServerUnsupportedError(\n        `codex CLI does not support the app-server subcommand: ${stderrTail.trim().slice(0, 400)}`\n      )\n    }\n    throw error\n  } finally {\n    try {\n      child.stdin.end()\n    } catch {\n      // stdin may already be destroyed after a kill; reaping below still runs.\n    }\n    if (!exited) {\n      // Why: the server exits promptly on stdin EOF; the grace period only\n      // bounds a wedged child before the guaranteed SIGKILL reap.\n      await waitForProcessExitUntil(exitPromise, 1500)\n      if (!exited) {\n        killCodexAppServerProcessTree(child)\n        await waitForProcessExitUntil(exitPromise, 1000)\n      }","sourceCodeStart":276,"sourceCodeEnd":312,"githubUrl":"https://github.com/stablyai/orca/blob/1136503c6a231a16dce8f921f6fadb63d181e8db/src/main/codex/codex-app-server-session.ts#L276-L312","documentation":"Thrown as CodexAppServerUnsupportedError in the session's outer catch when an error escaped the body that is NOT already a typed unsupported/timeout error, but the captured stderr tail matches stderrIndicatesMissingAppServer. This upgrades a generic early-exit/spawn failure into the typed unsupported signal when codex's own stderr proves the subcommand is absent — so the capability cache can suppress future probes.","triggerScenarios":"The codex child exited before completing initialize (or never started the JSON-RPC loop) and printed a 'no such subcommand: app-server' style message to stderr; the body threw a plain Error whose message didn't carry the unsupported signal, but stderr does.","commonSituations":"Old codex build where 'codex app-server' is rejected at the CLI parser; a codex wrapper script that doesn't forward the subcommand; a PATH resolution that picks up a different (older) codex binary.","solutions":["Run: codex app-server (if it errors with an unknown-subcommand message, upgrade codex).","Ensure PATH or resolveCodexCommand points at a current codex binary.","Once thrown, let the capability cache mark this host unsupported so probes stop.","Keep the host on the managed-home lane (the real-home installer falls back to 'unavailable').","If using a wrapper script, confirm it forwards argv including 'app-server'."],"exampleFix":null,"handlingStrategy":"type-guard","validationCode":"// Cheap pre-check: does 'codex app-server' parse?\n// spawnSync(codex, ['app-server', '--help']) and inspect exit/stderr once per host; cache it.","typeGuard":"import { isCodexAppServerUnsupportedError } from './codex-app-server-session'\n// This error is CodexAppServerUnsupportedError (thrown from the outer catch upgrade).","tryCatchPattern":"try {\n  await runCodexAppServerSession(invocation, body)\n} catch (error) {\n  if (isCodexAppServerUnsupportedError(error)) {\n    capabilityCache.setUnsupported(host, 'app-server-subcommand')\n    // stay on managed lane permanently until codex upgrade\n  } else {\n    throw error\n  }\n}","preventionTips":["Probe 'codex app-server' availability once per host and cache unsupported.","Pin PATH/resolveCodexCommand to a current codex binary.","Treat stderr-detected missing-subcommand as permanent; do not retry eagerly.","Re-probe only after a detected codex version change."],"tags":["codex","app-server","capability","unsupported","stderr","version-compat"],"backgroundTag":null,"analyzedSha":"1136503c6a231a16dce8f921f6fadb63d181e8db","analyzedAt":"2026-08-12T23:15:58.167Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}