{"record":{"id":"f280328e308e7703","repo":"musistudio/claude-code-router","slug":"the-ccr-artifact-request-failed","errorCode":null,"errorMessage":"The CCR artifact request failed.","messagePattern":"The CCR artifact request failed\\.","errorType":"http","errorClass":null,"httpStatus":null,"severity":"error","filePath":"packages/core/src/agents/codex/media-preview-bridge.ts","lineNumber":302,"sourceCode":"  }\n  const keys = [...url.searchParams.keys()];\n  const token = url.searchParams.get(\"token\") || \"\";\n  if (keys.length !== 1 || keys[0] !== \"token\" || !/^[A-Za-z0-9_-]{32}$/.test(token)) {\n    throw new Error(\"Artifact URL contains an invalid access token.\");\n  }\n  return { artifactId, url };\n}\n\nasync function loadCodexMediaArtifact(validated: ValidatedArtifactUrl, signal: AbortSignal): Promise<LoadedMediaArtifact> {\n  let response: Response;\n  try {\n    response = await fetch(validated.url, {\n      headers: { accept: \"image/*, video/*\" },\n      redirect: \"error\",\n      signal\n    });\n  } catch {\n    throw new Error(\"The CCR artifact request failed.\");\n  }\n  if (!response.ok) throw new Error(`The CCR artifact endpoint returned HTTP ${response.status}.`);\n  if (response.redirected) throw new Error(\"The CCR artifact endpoint attempted a redirect.\");\n  const declaredMimeType = (response.headers.get(\"content-type\") || \"\").split(\";\", 1)[0].trim().toLowerCase();\n  const declaredKind = mediaKind(declaredMimeType);\n  if (!declaredKind) throw new Error(\"The CCR artifact endpoint returned a non-media content type.\");\n  const maxBytes = declaredKind === \"video\" ? codexMediaPreviewMaxVideoBytes : codexMediaPreviewMaxImageBytes;\n  const declaredLength = Number(response.headers.get(\"content-length\") || \"0\");\n  if (declaredLength && (!Number.isSafeInteger(declaredLength) || declaredLength < 1 || declaredLength > maxBytes)) {\n    throw new Error(\"The CCR media artifact exceeds the inline preview size limit.\");\n  }\n  if (response.headers.get(\"content-encoding\") && response.headers.get(\"content-encoding\") !== \"identity\") {\n    throw new Error(\"Compressed CCR media artifacts are not accepted for inline preview.\");\n  }\n  if (!response.body) throw new Error(\"The CCR artifact response had no body.\");\n  const reader = response.body.getReader();\n  const chunks: Buffer[] = [];\n  let total = 0;","sourceCodeStart":284,"sourceCodeEnd":320,"githubUrl":"https://github.com/musistudio/claude-code-router/blob/99f24806c6a2c660b16e53e95211c517448a6c90/packages/core/src/agents/codex/media-preview-bridge.ts#L284-L320","documentation":"loadCodexMediaArtifact fetches a media (image/video) artifact from the Codex CCR artifact endpoint, and this error means the fetch itself threw — network failure, DNS error, TLS problem, invalid redirect (redirect: 'error'), or the request was aborted via the AbortSignal. The catch block deliberately discards the underlying cause and rethrows this generic message.","triggerScenarios":"Calling artifact() for a CCR media attachment when the artifact URL is unreachable, the endpoint responds with a 3xx redirect (redirect: 'error' makes any redirect throw), the AbortSignal fires before completion, or fetch rejects due to DNS/TLS/network errors.","commonSituations":"Running in a sandboxed/offline CI environment, a proxy or firewall blocking the artifact host, the artifact URL being invalidated by restarting/expiring the CCR session, or an aggressive timeout on the AbortSignal.","solutions":["Verify the artifact host is reachable from the process (curl the validated URL with accept: image/*, video/*)","Check whether the URL redirects — redirects are rejected by design; fetch the artifact through its canonical non-redirecting URL","If an AbortSignal/timeout is being passed, confirm it isn't firing before the download completes","Inspect the original fetch error by temporarily logging the caught value before the rethrow, since the cause is swallowed","If the CCR session was restarted, re-request the artifact reference to get a fresh URL"],"exampleFix":"// before\ntry {\n  const media = await bridge.artifact(ref);\n} catch (e) {\n  console.error(e.message); // \"The CCR artifact request failed.\" — cause lost\n}\n\n// after (in media-preview-bridge.ts, keep the cause)\n} catch (cause) {\n  throw new Error(\"The CCR artifact request failed.\", { cause });\n}","handlingStrategy":"retry","validationCode":"// Pre-flight reachability check (best-effort) before requesting the artifact\nasync function artifactReachable(url: string, signal?: AbortSignal): Promise<boolean> {\n  try {\n    const res = await fetch(url, { method: 'HEAD', redirect: 'error', signal });\n    return res.ok;\n  } catch { return false; }\n}","typeGuard":"function isArtifactRequestFailure(e: unknown): boolean {\n  return e instanceof Error && e.message === 'The CCR artifact request failed.';\n}","tryCatchPattern":"try {\n  const media = await bridge.artifact(ref);\n} catch (e) {\n  if (isArtifactRequestFailure(e)) {\n    await sleep(backoffMs);\n    return bridge.artifact(ref); // network blips are often transient\n  }\n  throw e;\n}","preventionTips":["Keep CCR sessions alive so artifact URLs don't expire","Ensure network/proxy access to the artifact host from the runtime","Use a generous AbortSignal timeout relative to artifact size"],"tags":["network","fetch","codex","media-artifact","redirect"],"backgroundTag":"fetch-network-request-failed","analyzedSha":"99f24806c6a2c660b16e53e95211c517448a6c90","analyzedAt":"2026-08-27T04:11:01.184Z","schemaVersion":2},"datasetVersion":"2026-08-27T08:17:20.692Z"}