can1357/oh-my-pi · error
${errorMessage(first.error)}${outputSuffix()}
Error message
${errorMessage(first.error)}${outputSuffix()} What it means
While racing the PTY-driven Claude run against the /v1/messages capture, if the capture side fails first (capture-error), this error surfaces the capture failure's message plus any captured output as context. It means the proxy/capture pipeline itself broke before a response exchange could be recorded.
Source
Thrown at packages/coding-agent/src/cli/claude-trace-cli.ts:769
} catch (error) {
ptyOutput += `\n[omp input write failed: ${errorMessage(error)}]\n`;
}
})();
const captureRace = proxy.waitForCapture(timeoutMs).then(
exchange => ({ kind: "capture" as const, exchange }),
error => ({ kind: "capture-error" as const, error }),
);
const ptyRace = runPromise.then(
() => ({ kind: "pty-exit" as const }),
error => ({ kind: "pty-error" as const, error }),
);
const first = await Promise.race([captureRace, ptyRace]);
if (first.kind === "capture") {
await shutdownPty(session, runPromise);
return first.exchange;
}
if (first.kind === "capture-error") {
throw new Error(`${errorMessage(first.error)}${outputSuffix()}`);
}
const late = await Promise.race([captureRace, Bun.sleep(250).then(() => ({ kind: "late-timeout" as const }))]);
if (late.kind === "capture") {
await shutdownPty(session, runPromise);
return late.exchange;
}
if (first.kind === "pty-error") {
throw new Error(
`Claude command failed before /v1/messages completed: ${errorMessage(first.error)}${outputSuffix()}`,
);
}
throw new Error(`Claude command exited before /v1/messages completed${outputSuffix()}`);
} finally {
terminal.dispose();
await proxy.stop();
}
}
View on GitHub (pinned to 9690622007)
Solutions
- Read the embedded errorMessage and outputSuffix() capture output in the thrown message to identify the underlying proxy failure.
- Free the proxy port (default 8080) or pass a different port if another proxy is bound.
- Verify NODE_TLS_REJECT_UNAUTHORIZED=0 and the debug cert env actually reached the spawned claude process.
- Retry the trace — transient network failures during capture produce this same path.
Example fix
// before: port conflict $ omp claude-trace # proxy on 8080 already used // after $ omp claude-trace --proxy-port 8123
Defensive patterns
Strategy: try-catch
Validate before calling
// before starting the trace
const portFree = !(await Bun.$`ss -ltn`.quiet().nothrow().text()).includes(`:${proxyPort} `);
if (!portFree) throw new Error(`Proxy port ${proxyPort} already in use`); Try / catch
try {
const exchange = await runTrace();
} catch (err) {
// message embeds the underlying capture error + output suffix — surface both
logger.error("capture failed", { cause: (err as Error).message });
} Prevention
- Check the proxy port isn't already bound before starting
- Confirm NODE_TLS_REJECT_UNAUTHORIZED=0 and the debug cert env reached the spawned claude process
- Test general connectivity to the upstream API through the proxy before tracing
When it happens
Trigger: The local CONNECT proxy or TLS bridge fails — port 8080 already in use, TLS handshake failure with Claude Code, or an exception inside the capture pipeline — and that rejection wins the Promise.race against the PTY session.
Common situations: Another process is already listening on the proxy port; the proxy cert/env injection didn't reach the spawned Claude process; network errors reaching api.anthropic.com through the proxy; firewall blocking loopback MITM.
Related errors
- Proxy tunnel aborted
- Internal TLS bridge did not bind to a TCP address
- Proxy configuration uses a scheme Bun's fetch cannot use${de
- timed out: {command}
- V2 remote compaction failed (${response.status} ${response.s
AI-assisted analysis of can1357/oh-my-pi@9690622007 (2026-08-31).
Data as JSON: /api/errors/f7c305dac2e43efe.
Report an issue: GitHub.