{"record":{"id":"eb42230703d474e8","repo":"musistudio/claude-code-router","slug":"the-ccr-artifact-endpoint-returned-a-non-media-con","errorCode":null,"errorMessage":"The CCR artifact endpoint returned a non-media content type.","messagePattern":"The CCR artifact endpoint returned a non-media content type\\.","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"packages/core/src/agents/codex/media-preview-bridge.ts","lineNumber":308,"sourceCode":"  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;\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) {","sourceCodeStart":290,"sourceCodeEnd":326,"githubUrl":"https://github.com/musistudio/claude-code-router/blob/99f24806c6a2c660b16e53e95211c517448a6c90/packages/core/src/agents/codex/media-preview-bridge.ts#L290-L326","documentation":"The Content-Type returned by the CCR artifact endpoint is not a recognized image/* or video/* MIME type. mediaKind() maps declared MIME types to 'image' or 'video'; anything else (application/octet-stream, text/html, JSON error payloads) fails this guard before any bytes are buffered.","triggerScenarios":"The server serves the artifact with application/octet-stream or a missing/garbage Content-Type; the endpoint actually returned a JSON/HTML error page with a 200 status; a genuinely non-media artifact was referenced.","commonSituations":"CDN or object storage defaulting to application/octet-stream when metadata wasn't set; error pages that return 200; referencing an attachment whose kind isn't image or video.","solutions":["Manually fetch the URL and inspect the raw Content-Type header to see what the server actually sends","If the server mislabels media as application/octet-stream, fix the artifact upload to set the correct MIME type","If the response is an HTML/JSON error page, investigate why the endpoint returned 200 with an error body","Only request artifacts that are actually images or videos"],"exampleFix":null,"handlingStrategy":"validation","validationCode":"async function declaresMediaType(url: string): Promise<boolean> {\n  const res = await fetch(url, { method: 'HEAD' });\n  const ct = (res.headers.get('content-type') || '').split(';', 1)[0].trim().toLowerCase();\n  return ct.startsWith('image/') || ct.startsWith('video/');\n}","typeGuard":"function isNonMediaTypeRejection(e: unknown): boolean {\n  return e instanceof Error && e.message.includes('non-media content type');\n}","tryCatchPattern":"try {\n  const media = await bridge.artifact(ref);\n} catch (e) {\n  if (isNonMediaTypeRejection(e)) return renderAsDownload(ref);\n  throw e;\n}","preventionTips":["Only reference image/video attachments for preview","Set correct MIME type metadata when uploading artifacts","Watch for 200-status error pages masquerading as artifacts"],"tags":["content-type","validation","media","codex"],"backgroundTag":"invalid-content-type-header","analyzedSha":"99f24806c6a2c660b16e53e95211c517448a6c90","analyzedAt":"2026-08-27T04:11:01.184Z","schemaVersion":2},"datasetVersion":"2026-08-27T08:17:20.692Z"}