openai/codex-plugin-cc · error · Error
codex app-server stdin is not available.
Error message
codex app-server stdin is not available.
What it means
SpawnedCodexAppServerClient.sendMessage writes a JSONL line to this.proc.stdin. If proc is null or proc.stdin is null/destroyed (process not spawned, already exited, or stdin closed during shutdown), it throws. This is the direct-transport variant; the broker variant has its own socket check.
Source
Thrown at plugins/codex/scripts/lib/app-server.mjs:272
} catch {
// Best-effort cleanup inside an unref'd timer — swallow errors
// to avoid crashing the host process during shutdown.
}
} else {
this.proc.kill("SIGTERM");
}
}
}, 50).unref?.();
}
await this.exitPromise;
}
sendMessage(message) {
const line = `${JSON.stringify(message)}\n`;
const stdin = this.proc?.stdin;
if (!stdin) {
throw new Error("codex app-server stdin is not available.");
}
stdin.write(line);
}
}
class BrokerCodexAppServerClient extends AppServerClientBase {
constructor(cwd, options = {}) {
super(cwd, options);
this.transport = "broker";
this.endpoint = options.brokerEndpoint;
}
async initialize() {
await new Promise((resolve, reject) => {
const target = parseBrokerEndpoint(this.endpoint);
this.socket = net.createConnection({ path: target.path });
this.socket.setEncoding("utf8");
this.socket.on("connect", resolve);View on GitHub (pinned to db52e28f4d)
Solutions
- Always await client.initialize() (or use CodexAppServerClient.connect which calls it) before any request.
- Do not issue requests after close() or after observing process exit; check the closed/exit state.
- Handle process exit errors (handleExit rejects pending requests) and recreate the client if needed.
Example fix
// before
client.request('turn/start', params); // before initialize / after exit
// after
await client.initialize();
await client.request('turn/start', params); Defensive patterns
Strategy: validation
Validate before calling
if (!client.proc?.stdin) throw new Error('stdin unavailable; (re)initialize'); Type guard
/** @param {object} c @returns {boolean} */
function hasStdin(c) { return Boolean(c.proc?.stdin); } Try / catch
try {
await client.request(method, params);
} catch (e) {
if (/stdin is not available/.test(e.message)) { /* reinitialize */ }
else throw e;
} Prevention
- Await initialize()/connect() before sending.
- Treat process-exit events as terminal and recreate the client.
When it happens
Trigger: Calling request()/notify() before initialize() has spawned the process (proc undefined), or after the codex process exited and stdin is gone. close() ends stdin, so a post-close request hits this.
Common situations: A race where handleExit fires (process crash) but a queued request still calls sendMessage; or invoking request before awaiting initialize().
Related errors
- codex app-server broker connection is not connected.
- codex app-server client is closed.
- Missing broker endpoint.
- Broker pipe endpoint is missing its path.
- Broker Unix socket endpoint is missing its path.
AI-assisted analysis of openai/codex-plugin-cc@db52e28f4d (2026-08-13).
Data as JSON: /api/errors/46634f7c1d6263fc.
Report an issue: GitHub.