{"record":{"id":"1d6404ba215db149","repo":"musistudio/claude-code-router","slug":"http-response-status-from-ccr-remote-sync","errorCode":null,"errorMessage":"HTTP  + response.status +  from CCR remote sync","messagePattern":"HTTP  \\+ response\\.status \\+  from CCR remote sync","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/core/src/agents/codex/cli-middleware-runtime.ts","lineNumber":5078,"sourceCode":"        this.pollTimer = setTimeout(() => this.pollInbound(onInbound), numberEnv(\"CCR_REMOTE_SYNC_POLL_INTERVAL_MS\", 2000));\n      });\n  }\n\n  async request(method, suffix, body) {\n    const controller = new AbortController();\n    const timeout = setTimeout(() => controller.abort(), numberEnv(\"CCR_REMOTE_SYNC_REQUEST_TIMEOUT_MS\", 5000));\n    const headers = { \"accept\": \"application/json\" };\n    if (body !== undefined) headers[\"content-type\"] = \"application/json\";\n    if (this.apiKey) headers.authorization = \"Bearer \" + this.apiKey;\n    try {\n      const response = await fetch(remoteSyncUrl(this.options.endpoint, suffix), {\n        method,\n        headers,\n        body: body === undefined ? undefined : JSON.stringify(body),\n        signal: controller.signal\n      });\n      if (!response.ok) {\n        throw new Error(\"HTTP \" + response.status + \" from CCR remote sync\");\n      }\n      return await response.json();\n    } finally {\n      clearTimeout(timeout);\n    }\n  }\n}\n\nasync function readRemoteSyncApiKey() {\n  const direct = nonEmptyEnv(\"CCR_REMOTE_SYNC_API_KEY\");\n  if (direct) return direct;\n  const file = nonEmptyEnv(\"CCR_REMOTE_SYNC_API_KEY_FILE\");\n  if (file) {\n    try {\n      const content = fs.readFileSync(expandHome(file), \"utf8\");\n      return String(content || \"\").split(/\\r?\\n/).map((line) => line.trim()).find(Boolean) || \"\";\n    } catch (error) {\n      log(\"remote_sync_api_key_file_failed\", { error: formatError(error), file });","sourceCodeStart":5060,"sourceCodeEnd":5096,"githubUrl":"https://github.com/musistudio/claude-code-router/blob/99f24806c6a2c660b16e53e95211c517448a6c90/packages/core/src/agents/codex/cli-middleware-runtime.ts#L5060-L5096","documentation":"Thin fetch wrapper around the CCR remote-sync HTTP endpoint: any non-2xx status from fetch triggers this throw (with the status code in the message), after which the JSON body is never parsed. It signals the remote sync service rejected or failed the request.","triggerScenarios":"Any ccrRemoteSync call where response.ok is false: 401/403 auth failures, 404 wrong endpoint, 4xx bad payload, 5xx server errors, or a proxy returning an error page — all within the request's AbortController timeout.","commonSituations":"Expired or missing sync credentials; wrong CCR base URL configured; reverse proxy/gateway intercepting the request; CCR service outage or version mismatch changing routes; request body exceeding gateway limits (413).","solutions":["Check the status code in the message: 401/403 → refresh credentials, 404 → verify endpoint URL/config, 5xx → retry later","Print/inspect the response body (it is discarded before the throw) to get the server's error detail","Verify the CCR base URL and auth headers in config against a working curl request","Retry with backoff for transient 502/503/504 from gateways"],"exampleFix":"// before\nif (!response.ok) throw new Error(\"HTTP \" + response.status + \" from CCR remote sync\");\n\n// after\nif (!response.ok) {\n  const detail = await response.text().catch(() => \"\");\n  throw new Error(`HTTP ${response.status} from CCR remote sync: ${detail.slice(0, 200)}`);\n}","handlingStrategy":"retry","validationCode":"null","typeGuard":"null","tryCatchPattern":"try { return await ccrRemoteSync(url, opts); } catch (e) { const m = /HTTP (\\d+) from CCR/.exec(String(e)); if (m && [\"502\",\"503\",\"504\"].includes(m[1])) return await backoffRetry(() => ccrRemoteSync(url, opts)); throw e; }","preventionTips":["Verify CCR endpoint URL and credentials with curl during setup","Retry 5xx responses with exponential backoff","Capture response bodies for diagnostics on non-2xx statuses"],"tags":["http","remote-sync","fetch","status-code"],"backgroundTag":"http-error-response","analyzedSha":"99f24806c6a2c660b16e53e95211c517448a6c90","analyzedAt":"2026-08-27T04:11:01.184Z","schemaVersion":2},"datasetVersion":"2026-08-27T08:17:20.692Z"}