{"record":{"id":"69c4e2c7cae72655","repo":"musistudio/claude-code-router","slug":"the-ccr-media-artifact-exceeds-the-inline-preview","errorCode":null,"errorMessage":"The CCR media artifact exceeds the inline preview size limit.","messagePattern":"The CCR media artifact exceeds the inline preview size limit\\.","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"packages/core/src/agents/codex/media-preview-bridge.ts","lineNumber":312,"sourceCode":"  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;\n  while (true) {\n    const part = await reader.read();\n    if (part.done) break;\n    if (!part.value?.byteLength) continue;\n    total += part.value.byteLength;\n    if (total > maxBytes) {\n      await reader.cancel();\n      throw new Error(\"The CCR media artifact exceeds the inline preview size limit.\");\n    }\n    chunks.push(Buffer.from(part.value));","sourceCodeStart":294,"sourceCodeEnd":330,"githubUrl":"https://github.com/musistudio/claude-code-router/blob/99f24806c6a2c660b16e53e95211c517448a6c90/packages/core/src/agents/codex/media-preview-bridge.ts#L294-L330","documentation":"The Content-Length header on the artifact response is missing, non-numeric, non-positive, or exceeds the inline preview cap (codexMediaPreviewMaxImageBytes for images, codexMediaPreviewMaxVideoBytes for videos). This is a pre-flight size check so oversized media is rejected before streaming the body.","triggerScenarios":"Artifact Content-Length > maxBytes for its declared kind; Content-Length header of '0' is fine, but a malformed/negative/non-safe-integer value triggers the same rejection.","commonSituations":"Trying to inline a 4K screenshot or long screen recording that exceeds the preview budget; a server sending a wrong Content-Length (e.g. '*' or a negative number); proxy-rewritten headers producing invalid lengths.","solutions":["Check the artifact's actual size (HEAD or Content-Length) against the limits before requesting an inline preview","If the media is legitimately large, render it as a link/external reference instead of an inline preview","If the header value is malformed from your server, fix the endpoint to send a valid numeric Content-Length or omit it (omission is tolerated — streaming check in error 57 still applies)"],"exampleFix":"// before\nconst media = await bridge.artifact(ref); // throws if > limit\n\n// after\nif (ref.size != null && ref.size > maxInlineBytes) {\n  renderAsLink(ref.url);\n} else {\n  const media = await bridge.artifact(ref);\n}","handlingStrategy":"validation","validationCode":"async function withinPreviewLimit(url: string, maxBytes: number): Promise<boolean> {\n  const res = await fetch(url, { method: 'HEAD' });\n  const len = Number(res.headers.get('content-length') || '0');\n  return !len || (len >= 1 && len <= maxBytes);\n}","typeGuard":"function isSizeLimitRejection(e: unknown): boolean {\n  return e instanceof Error && e.message.includes('exceeds the inline preview size limit');\n}","tryCatchPattern":"try {\n  const media = await bridge.artifact(ref);\n} catch (e) {\n  if (isSizeLimitRejection(e)) return renderAsLink(ref);\n  throw e;\n}","preventionTips":["Check artifact size against the image/video byte limits before inline preview","Prefer links for large screenshots/recordings","Ensure uploads set accurate Content-Length"],"tags":["size-limit","content-length","validation","media"],"backgroundTag":"response-size-limit-exceeded","analyzedSha":"99f24806c6a2c660b16e53e95211c517448a6c90","analyzedAt":"2026-08-27T04:11:01.184Z","schemaVersion":2},"datasetVersion":"2026-08-27T08:17:20.692Z"}