Skip to content

fix: validate Responses proxy liveness before reuse - #134

Open
sylvesterkaczmarek wants to merge 3 commits into
openai:mainfrom
sylvesterkaczmarek:fix/stale-proxy-server-info
Open

fix: validate Responses proxy liveness before reuse#134
sylvesterkaczmarek wants to merge 3 commits into
openai:mainfrom
sylvesterkaczmarek:fix/stale-proxy-server-info

Conversation

@sylvesterkaczmarek

Copy link
Copy Markdown

Summary

Verify that an existing Responses API proxy is actually alive before reusing its server-info file.

Fixes #133.

Problem

codex-action currently treats a non-empty server-info JSON file as proof that the proxy is still running:

if [ -s "$SERVER_INFO_FILE" ]; then
  echo "server_info_file_exists=true" >> "$GITHUB_OUTPUT"
fi

The proxy writes { "port": ..., "pid": ... } once at startup. If that process later exits unexpectedly, the file can remain behind.

A subsequent action invocation using the same run/Codex-home path then:

  1. sees the stale non-empty file;
  2. skips Start Responses API proxy;
  3. successfully reads the stale port from the JSON;
  4. configures Codex to use a loopback endpoint where no proxy is listening.

The resulting connection failure occurs well after the action has incorrectly reported that the proxy was reusable.

Fix

Replace the file-size-only status check with a dependency-free Node helper that validates the complete reusable state:

  • server-info JSON exists and is parseable;
  • pid is a positive integer;
  • port is an integer in the valid TCP port range;
  • the recorded process still exists (process.kill(pid, 0); EPERM is treated as existing);
  • the recorded loopback port accepts a TCP connection.

Only when all checks pass does the helper emit:

server_info_file_exists=true

Missing, empty, malformed, dead-process, or closed-port state is reported as false. Stale non-empty metadata is removed so the existing proxy-start step can create a fresh server-info file.

The cleanup path first removes files normally and, on Unix, falls back to non-interactive sudo rm for server-info files that the action previously hardened to root ownership.

Why check both PID and port

A process check alone is insufficient because a live process does not prove that the expected proxy listener is still available. A port check alone is also insufficient because a port can be reused by another process. Requiring both substantially narrows false reuse while keeping the check local and credential-free.

The helper does not send an HTTP request to the proxy, so it cannot accidentally trigger /shutdown or send application data.

Regression coverage

Added direct Node-stdlib tests for four states:

  • missing server-info file -> false;
  • malformed server-info file -> remove it and return false;
  • dead PID/closed port -> remove stale metadata and return false;
  • live current PID plus a real loopback listener -> true and preserve the file.

The live case uses an ephemeral net.Server, so it exercises the same TCP-connect path as production without depending on the Codex proxy package or network access.

Scope

This deliberately does not change proxy startup, API-key handling, upstream endpoint configuration, server-info format, Codex configuration, or the proxy package itself.

There are no changes under src/, so the checked-in dist/main.js bundle remains valid and does not need regeneration.

Validation

  • branch is based directly on current upstream main (c385816875cc2fc8e033ed9d1cba96f8c331210e)
  • branch is 0 commits behind upstream
  • diff is limited to action.yml, the new helper, and its focused test
  • helper/test use only Node built-ins already available after the action's Node setup step

Full repository validation is left to the repository's GitHub Actions checks.

Risk

Low. Existing healthy proxies continue to be reused. The behavior changes only when the previously trusted server-info file cannot demonstrate a live process and listener, in which case starting a new proxy is safer than configuring Codex against stale state.

@github-actions

github-actions Bot commented Aug 18, 2026

Copy link
Copy Markdown

All contributors have signed the CLA ✍️ ✅
Posted by the CLA Assistant Lite bot.

@sylvesterkaczmarek

Copy link
Copy Markdown
Author

I have read the CLA Document and I hereby sign the CLA

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Stale server-info files can make later action invocations reuse a dead Responses proxy

1 participant