Skip to content

ocx init busy-loops at ~100% CPU after piped stdin reaches EOF #754

Description

@nostitos

Client or integration

Other — ocx CLI directly

Area

CLI

Summary

Running the interactive ocx init command with finite piped stdin left its bundled Bun process alive and consuming approximately 99% CPU after stdin reached EOF.

The process remained alive for nearly 13 hours. The unrelated OpenCodex background proxy remained healthy and used normal CPU. Even if piped/non-interactive use is unsupported, ocx init should complete, report EOF/non-TTY input as an error, or exit; it should not busy-loop indefinitely.

Reproduction

The incident was triggered with:

printf '1\n\n\nn\n' | ocx init

Observed steps:

  1. Run the command above with OpenCodex 2.7.43.
  2. Allow the finite input pipe to reach EOF.
  3. Inspect the surviving process tree with ps.
  4. Observe that the Bun child remains runnable at approximately 99% CPU instead of exiting.

The surviving process tree was:

/bin/zsh -c printf ... | ocx init
  node .../bin/ocx init
    bun.exe .../src/cli/index.ts init

For an isolated test that avoids injecting into Codex, use a temporary OpenCodex home and explicit "no" answers:

ocx_tmp="$(mktemp -d)"
printf '1\n\nn\nn\n' | OPENCODEX_HOME="$ocx_tmp" ocx init

I have not rerun the isolated command after discovering the incident because the original process evidence already establishes the indefinite high-CPU failure and an uncontrolled retry could create another busy-looping process.

Expected behavior: consume the answers and complete, exit nonzero with a useful EOF message, or reject non-TTY input immediately.

Actual behavior: the Bun initializer survived EOF and continuously consumed one CPU core until killed manually.

Version

2.7.43 (@bitkyc08/opencodex), bundled Bun 1.3.14, Node launcher 20.19.5

Operating system

macOS 26.5.1 (25F80), Apple Silicon / ARM64

Provider and model

Not provider-specific. The initializer selected the first/default ChatGPT-forward provider entry.

Logs or error output

PID    PPID   %CPU  ELAPSED   COMMAND
63100  1       0.0  12:55:45 /bin/zsh -c printf ... | ocx init
63102  63100   0.0  12:55:45 node .../bin/ocx init
63103  63102  98.9  12:55:45 bun.exe .../src/cli/index.ts init

Additional observations:

  • The Bun initializer had no open network sockets.
  • File descriptors 0, 1, and 2 were connected only to pipes.
  • A two-second macOS sample showed the main Bun thread continuously active/runnable in its event-loop/readline path.
  • The separate ocx start --port 10100 service process remained healthy.

Possible code area: src/cli/init.ts creates one readline.Interface, implements prompts with rl.question(), has no explicit pending-question EOF/close handling, and reaches prompt.close() only through normal completion. The sample was unsymbolicated, so this is a suspected area rather than a claimed definitive root cause.

Suggested safeguards:

  • Handle readline close/EOF and settle any pending prompt.
  • Put prompt.close() in a finally block.
  • Explicitly reject non-TTY ocx init runs or queue piped lines safely.
  • Add a finite-piped-input regression test with a short timeout.

Screenshots and supporting files

A macOS process sample was captured locally. Its relevant result is summarized above; it contains local filesystem paths, so it has not been attached publicly.

Redacted configuration

{
  "providerSpecific": false,
  "command": "ocx init"
}

Checks

  • I searched existing issues and documentation.
  • I removed secrets, tokens, account details, request credentials, and personal data.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions