{"record":{"id":"f7c305dac2e43efe","repo":"can1357/oh-my-pi","slug":"errormessage-first-error-outputsuffix","errorCode":null,"errorMessage":"${errorMessage(first.error)}${outputSuffix()}","messagePattern":"\\$\\{errorMessage\\(first\\.error\\)\\}\\$\\{outputSuffix\\(\\)\\}","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"packages/coding-agent/src/cli/claude-trace-cli.ts","lineNumber":769,"sourceCode":"\t\t\t} catch (error) {\n\t\t\t\tptyOutput += `\\n[omp input write failed: ${errorMessage(error)}]\\n`;\n\t\t\t}\n\t\t})();\n\t\tconst captureRace = proxy.waitForCapture(timeoutMs).then(\n\t\t\texchange => ({ kind: \"capture\" as const, exchange }),\n\t\t\terror => ({ kind: \"capture-error\" as const, error }),\n\t\t);\n\t\tconst ptyRace = runPromise.then(\n\t\t\t() => ({ kind: \"pty-exit\" as const }),\n\t\t\terror => ({ kind: \"pty-error\" as const, error }),\n\t\t);\n\t\tconst first = await Promise.race([captureRace, ptyRace]);\n\t\tif (first.kind === \"capture\") {\n\t\t\tawait shutdownPty(session, runPromise);\n\t\t\treturn first.exchange;\n\t\t}\n\t\tif (first.kind === \"capture-error\") {\n\t\t\tthrow new Error(`${errorMessage(first.error)}${outputSuffix()}`);\n\t\t}\n\t\tconst late = await Promise.race([captureRace, Bun.sleep(250).then(() => ({ kind: \"late-timeout\" as const }))]);\n\t\tif (late.kind === \"capture\") {\n\t\t\tawait shutdownPty(session, runPromise);\n\t\t\treturn late.exchange;\n\t\t}\n\t\tif (first.kind === \"pty-error\") {\n\t\t\tthrow new Error(\n\t\t\t\t`Claude command failed before /v1/messages completed: ${errorMessage(first.error)}${outputSuffix()}`,\n\t\t\t);\n\t\t}\n\t\tthrow new Error(`Claude command exited before /v1/messages completed${outputSuffix()}`);\n\t} finally {\n\t\tterminal.dispose();\n\t\tawait proxy.stop();\n\t}\n}\n","sourceCodeStart":751,"sourceCodeEnd":787,"githubUrl":"https://github.com/can1357/oh-my-pi/blob/969062200754ea02cfac922e5ebb8c608c079e15/packages/coding-agent/src/cli/claude-trace-cli.ts#L751-L787","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"// before: port conflict\n$ omp claude-trace  # proxy on 8080 already used\n// after\n$ omp claude-trace --proxy-port 8123","handlingStrategy":"try-catch","validationCode":"// before starting the trace\nconst portFree = !(await Bun.$`ss -ltn`.quiet().nothrow().text()).includes(`:${proxyPort} `);\nif (!portFree) throw new Error(`Proxy port ${proxyPort} already in use`);","typeGuard":null,"tryCatchPattern":"try {\n  const exchange = await runTrace();\n} catch (err) {\n  // message embeds the underlying capture error + output suffix — surface both\n  logger.error(\"capture failed\", { cause: (err as Error).message });\n}","preventionTips":["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"],"tags":["proxy","network","tls","claude-code"],"backgroundTag":"capture-proxy-failed","analyzedSha":"969062200754ea02cfac922e5ebb8c608c079e15","analyzedAt":"2026-08-31T10:29:35.737Z","schemaVersion":2},"datasetVersion":"2026-08-31T14:17:45.589Z"}