{"record":{"id":"c3daf2ddfb0076ab","repo":"paperclipai/paperclip","slug":"opencode-api-path-request-failed-redact-stri","errorCode":null,"errorMessage":"OpenCode API ${path} request failed: ${redact(String(error), runtime.sensitiveValues)}","messagePattern":"OpenCode API (.+?) request failed: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"packages/paperclip-runner/src/drivers/opencode/opencode-server-driver.ts","lineNumber":2232,"sourceCode":"      stage: \"typescript_opencode_http_transport\",\n      ruleId: `opencode.http.${method}.${safeTraceRulePath(path)}`,\n      disposition: \"operator_only\",\n      reason: \"Sent an exact HTTP request body to the OpenCode app server\",\n    });\n  }\n  let response: Response;\n  try {\n    response = await fetcher(`${runtime.baseUrl}${path}`, {\n      ...init,\n      signal,\n      headers: {\n        Authorization: runtime.authHeader,\n        \"Content-Type\": \"application/json\",\n        ...init.headers,\n      },\n    });\n  } catch (error) {\n    throw new Error(\n      `OpenCode API ${path} request failed: ${redact(String(error), runtime.sensitiveValues)}`,\n    );\n  }\n  const responseRaw = await response.text();\n  const responseFrameId = runtime.trace?.frame({\n    direction: \"provider_to_client\",\n    raw: responseRaw,\n    transport: \"http_json\",\n    nativeMethod: `${method} ${path} ${response.status}`,\n  });\n  if (!response.ok) {\n    if (responseFrameId) {\n      runtime.trace?.interpretation({\n        frameId: responseFrameId,\n        stage: \"typescript_opencode_http_parse\",\n        ruleId: `opencode.http.error.${response.status}`,\n        disposition: \"rejected\",\n        reason: `OpenCode API returned HTTP ${response.status}`,","sourceCodeStart":2214,"sourceCodeEnd":2250,"githubUrl":"https://github.com/paperclipai/paperclip/blob/01ad8584922b5d85292b1723cae71fa0d9b07a19/packages/paperclip-runner/src/drivers/opencode/opencode-server-driver.ts#L2214-L2250","documentation":"Wraps any low-level failure of a request to the OpenCode HTTP API (fetch throwing — connection refused, DNS failure, TLS error, abort) into a single message including the request path. The error string is passed through redact() with the runtime's sensitive values so secrets are not leaked.","triggerScenarios":"The fetch call for `path` throws before a response is received: server not listening, wrong port, connection reset, request aborted, or TLS handshake failure.","commonSituations":"OpenCode server died between health-check and API use; port collision or the server bound to a different port than recorded in runtime; corporate proxy blocking localhost; ECONNREFUSED during startup races.","solutions":["Read the wrapped cause in the message (e.g. ECONNREFUSED) and verify the OpenCode server is running at the expected base URL/port.","Re-run the health check against the same baseUrl to confirm the server is still alive.","Check for startup races — ensure the server child process is fully listening before issuing API calls.","If the message contains a redaction marker, confirm the underlying error is not leaking credentials and that sensitiveValues is populated."],"exampleFix":"// before\nawait fetch(`${baseUrl}/session`, { method: \"POST\" }); // throws raw\n\n// after\ntry {\n  await fetch(`${baseUrl}/session`, { method: \"POST\" });\n} catch (e) {\n  if (String(e).includes(\"ECONNREFUSED\")) await restartOpenCodeServer();\n  throw e;\n}","handlingStrategy":"retry","validationCode":"const health = await fetch(`${baseUrl}/health`);\nif (!health.ok) throw new Error(`OpenCode server not reachable at ${baseUrl}`);","typeGuard":null,"tryCatchPattern":"try {\n  await callOpenCodeApi(path, init);\n} catch (e) {\n  if (e instanceof Error && e.message.includes(\"request failed\")) {\n    if (String(e.message).includes(\"ECONNREFUSED\")) await ensureServerRunning();\n    else if (String(e.message).includes(\"abort\")) checkTimeouts();\n  }\n  throw e;\n}","preventionTips":["Confirm the server child process is listening before issuing API calls","Use the port returned by the reservation step, not a hard-coded one","Set explicit fetch timeouts and handle AbortError distinctly"],"tags":["http","network","api","connection"],"backgroundTag":"api-request-failed","analyzedSha":"01ad8584922b5d85292b1723cae71fa0d9b07a19","analyzedAt":"2026-09-10T03:14:50.855Z","contentChangedAt":"2026-09-10T03:14:50.855Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}