{"record":{"id":"52f3b54524a7801a","repo":"vercel/ai","slug":"prodia-response-missing-multipart-boundary-in-cont-52f3b5","errorCode":null,"errorMessage":"Prodia response missing multipart boundary in content-type: ${contentType}","messagePattern":"Prodia response missing multipart boundary in content-type: (.+?)","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/prodia/src/prodia-video-model.ts","lineNumber":185,"sourceCode":"\nfunction createVideoMultipartResponseHandler() {\n  return async ({\n    response,\n  }: {\n    response: Response;\n  }): Promise<{\n    value: VideoMultipartResult;\n    responseHeaders: Record<string, string>;\n  }> => {\n    const contentType = response.headers.get('content-type') ?? '';\n    const responseHeaders: Record<string, string> = {};\n    response.headers.forEach((value, key) => {\n      responseHeaders[key] = value;\n    });\n\n    const boundaryMatch = contentType.match(/boundary=([^\\s;]+)/);\n    if (!boundaryMatch) {\n      throw new Error(\n        `Prodia response missing multipart boundary in content-type: ${contentType}`,\n      );\n    }\n    const boundary = boundaryMatch[1];\n\n    const arrayBuffer = await response.arrayBuffer();\n    const bytes = new Uint8Array(arrayBuffer);\n\n    const parts = parseMultipart(bytes, boundary);\n\n    let jobResult: ProdiaJobResult | undefined;\n    let videoBytes: Uint8Array | undefined;\n    let videoMediaType = 'video/mp4';\n\n    for (const part of parts) {\n      const contentDisposition = part.headers['content-disposition'] ?? '';\n      const partContentType = part.headers['content-type'] ?? '';\n","sourceCodeStart":167,"sourceCodeEnd":203,"githubUrl":"https://github.com/vercel/ai/blob/69428b1f8b037e4d118fb4853428d5c4e620493c/packages/prodia/src/prodia-video-model.ts#L167-L203","documentation":"The Prodia video model expects the provider API to answer video-generation jobs with a multipart response whose content-type declares a boundary. The handler extracts the boundary to split the body into the job JSON part and the output video part. A missing or boundary-less content-type means the body cannot be parsed, so the SDK throws immediately.","triggerScenarios":"A doGenerate call on the Prodia video model where the HTTP response content-type is missing, non-multipart (e.g. application/json, text/html), or multipart without a boundary= parameter — usually because an error body, proxy, or wrong endpoint answered instead of the normal multipart job response.","commonSituations":"Video-generation job failed server-side and Prodia returned a JSON/HTML error; CDN or reverse proxy stripping the boundary parameter; using an endpoint/model id that does not return multipart; expired or unauthorized API key.","solutions":["Check the content-type string embedded in the error message — application/json or text/html means an API-level error body was returned.","Validate your Prodia API key and quota; fix auth/credit issues so the real multipart response is produced.","Confirm the model id and endpoint are valid for the Prodia video API.","Remove or reconfigure intermediaries (proxy, CDN, worker) that rewrite or strip the content-type header."],"exampleFix":"// before: letting the SDK fail on an unexpected body\nconst video = await generateVideo({ model: prodia.video('...'), ... });\n\n// after: pre-check the endpoint returns multipart for a test job\nconst probe = await fetch(endpoint, { headers: { authorization: `Bearer ${key}` } });\nif (!(probe.headers.get('content-type') ?? '').includes('boundary=')) {\n  throw new Error('Unexpected Prodia response: ' + (await probe.text()));\n}","handlingStrategy":"validation","validationCode":"const ct = response.headers.get('content-type') ?? '';\nif (!/boundary=([^\\s;]+)/.test(ct)) {\n  console.error('Non-multipart Prodia response:', ct);\n  // treat as API-level failure before handing to the model\n}","typeGuard":"function isMultipartContentType(contentType: string | null): boolean {\n  return contentType != null && /boundary=([^\\s;]+)/.test(contentType);\n}","tryCatchPattern":"try {\n  const video = await generateVideo({ model: prodia.video(modelId), ... });\n} catch (error) {\n  if (error instanceof Error && error.message.includes('missing multipart boundary')) {\n    // content-type in message reveals whether an error page/JSON was returned\n  }\n  throw error;\n}","preventionTips":["Pre-check API key validity and quota before video jobs.","Inspect the content-type string in the error message to distinguish auth/credit errors from proxy issues.","Confirm model ids against the current Prodia video API.","Bypass or reconfigure CDNs that strip multipart headers."],"tags":["network","multipart","video","provider-response","prodia"],"backgroundTag":"missing-multipart-boundary","analyzedSha":"69428b1f8b037e4d118fb4853428d5c4e620493c","analyzedAt":"2026-08-30T12:32:21.016Z","schemaVersion":2},"datasetVersion":"2026-08-30T13:17:10.514Z"}