Skip to content

Share Codex CLI probe logic across startup and health checks - #812

Closed
Mitch515 wants to merge 2 commits into
pingdotgg:mainfrom
Mitch515:pr/codex-cli-probe-reliability
Closed

Mitch515 wants to merge 2 commits into
pingdotgg:mainfrom
Mitch515:pr/codex-cli-probe-reliability

Conversation

@Mitch515

@Mitch515 Mitch515 commented Mar 10, 2026 •

Copy link
Copy Markdown

What Changed

  • extract a shared codexCliProbe module for Codex CLI availability checks
  • use the shared probe path in both session startup and provider health checks
  • add probe-focused regression tests and simplify the existing health-check test coverage

Why

  • startup and health checks were probing the same dependency through separate logic paths
  • sharing the probe behavior keeps failure handling more consistent and reduces duplicate server logic

UI Changes

  • None

Checklist

  • This PR is small and focused
  • I explained what changed and why
  • I included before/after screenshots for any UI changes
  • I included a video for animation/interaction changes

Note

Share Codex CLI probe logic across startup and health checks

  • Introduces codexCliProbe.ts with async runCodexCliCommand, runCodexCliCommandWithRetry, and assertSupportedCodexCliVersion functions, replacing separate synchronous implementations in both startup and health check paths.
  • Default CLI command timeout increases from 4,000 ms to 15,000 ms, and commands are retried once on timeout before surfacing failure.
  • ProviderHealth.ts drops its effect/unstable/process dependency and now uses the shared promise-based runner via a new makeCheckCodexProviderStatus factory.
  • codexAppServerManager.ts now awaits the async version probe before spawning the app server.
  • Behavioral Change: error messages for missing binary, timeout, non-zero exit, and unsupported version are updated across both startup and health check flows.

Macroscope summarized c6b8f24.

@coderabbitai

coderabbitai Bot commented Mar 10, 2026 •

Copy link
Copy Markdown

Important

Review skipped

Auto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: ad7ff5ad-b80b-4e9c-8179-0a70c730e6dd

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@github-actions github-actions Bot added the vouch:unvouched PR author is not yet trusted in the VOUCHED list. label Mar 10, 2026
Comment on lines +198 to +201
const parsedVersion = parseCodexCliVersion(`${result.stdout}\n${result.stderr}`);
if (parsedVersion && !isCodexCliVersionSupported(parsedVersion)) {
throw new Error(formatCodexCliUpgradeMessage(parsedVersion));
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟢 Low src/codexCliProbe.ts:198

When parseCodexCliVersion returns null (e.g., malformed output or corrupted binary), the condition parsedVersion && !isCodexCliVersionSupported(parsedVersion) evaluates to falsy, so the function returns successfully without throwing. An unrecognized CLI version is silently treated as supported, risking downstream crashes or data corruption when the incompatible tool is invoked. Consider throwing an error when parsedVersion is null.

  const parsedVersion = parseCodexCliVersion(`${result.stdout}\n${result.stderr}`);
-  if (parsedVersion && !isCodexCliVersionSupported(parsedVersion)) {
+  if (!parsedVersion) {
+    throw new Error(`Failed to parse Codex CLI version from output.`);
+  }
+  if (!isCodexCliVersionSupported(parsedVersion)) {
     throw new Error(formatCodexCliUpgradeMessage(parsedVersion));
   }
🚀 Reply "fix it for me" or copy this AI Prompt for your agent:
In file apps/server/src/codexCliProbe.ts around lines 198-201:

When `parseCodexCliVersion` returns `null` (e.g., malformed output or corrupted binary), the condition `parsedVersion && !isCodexCliVersionSupported(parsedVersion)` evaluates to falsy, so the function returns successfully without throwing. An unrecognized CLI version is silently treated as supported, risking downstream crashes or data corruption when the incompatible tool is invoked. Consider throwing an error when `parsedVersion` is null.

Evidence trail:
apps/server/src/codexCliProbe.ts lines 198-201 (REVIEWED_COMMIT) - shows the condition `parsedVersion && !isCodexCliVersionSupported(parsedVersion)` which short-circuits when parsedVersion is null. apps/server/src/provider/codexCliVersion.ts lines 109-119 (REVIEWED_COMMIT) - shows `parseCodexCliVersion` returns `null` when regex match fails or parseSemver fails.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in c6b8f24. The probe now throws when version parsing fails instead of treating malformed output as supported.

Comment thread apps/server/src/codexCliProbe.ts Outdated
Comment on lines +89 to +97
child.once("close", (code) => {
finish(() =>
resolve({
stdout,
stderr,
code: typeof code === "number" ? code : 0,
}),
);
});

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Medium src/codexCliProbe.ts:89

When the Codex CLI process crashes (e.g., SIGSEGV, SIGABRT), Node.js emits the 'close' event with code === null. The current handler converts this null to 0, which conventionally indicates success. This masks crashes: callers like assertSupportedCodexCliVersion see code !== 0 as false and treat a crashing CLI as healthy/supported. Consider using a non-zero exit code (commonly 1 or 128 + signal) when code is null to properly signal failure.

    child.once("close", (code) => {
      finish(() =>
        resolve({
          stdout,
          stderr,
-          code: typeof code === "number" ? code : 0,
+          code: typeof code === "number" ? code : 1,
        }),
      );
    });
🚀 Reply "fix it for me" or copy this AI Prompt for your agent:
In file apps/server/src/codexCliProbe.ts around lines 89-97:

When the Codex CLI process crashes (e.g., `SIGSEGV`, `SIGABRT`), Node.js emits the 'close' event with `code === null`. The current handler converts this `null` to `0`, which conventionally indicates success. This masks crashes: callers like `assertSupportedCodexCliVersion` see `code !== 0` as false and treat a crashing CLI as healthy/supported. Consider using a non-zero exit code (commonly `1` or `128 + signal`) when `code` is `null` to properly signal failure.

Evidence trail:
apps/server/src/codexCliProbe.ts lines 89-96: `close` event handler with `code: typeof code === "number" ? code : 0` converts null to 0. apps/server/src/codexCliProbe.ts line 194: `if (result.code !== 0)` check in `assertSupportedCodexCliVersion` - passes when code is 0 (including crash-converted-to-0). apps/server/src/codexCliProbe.ts lines 12-17: `CodexCliCommandResult` interface defines `code: number`.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in c6b8f24. Null close codes are now treated as probe failures instead of success.

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

Labels

vouch:unvouched PR author is not yet trusted in the VOUCHED list.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants