{"record":{"id":"e61a868b3bffe131","repo":"vercel/ai","slug":"audio-format-must-be-provided-or-determinable-from","errorCode":null,"errorMessage":"Audio format must be provided or determinable from media type","messagePattern":"Audio format must be provided or determinable from media type","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"packages/ai/src/generate-speech/generated-audio-file.ts","lineNumber":45,"sourceCode":"  }) {\n    super({ data, mediaType });\n    let format = 'mp3';\n\n    // If format is not provided, try to determine it from the media type\n    if (mediaType) {\n      const mediaTypeParts = mediaType.split('/');\n\n      if (mediaTypeParts.length === 2) {\n        // Handle special cases for audio formats\n        if (mediaType !== 'audio/mpeg') {\n          format = mediaTypeParts[1];\n        }\n      }\n    }\n\n    if (!format) {\n      // TODO this should be an AI SDK error\n      throw new Error(\n        'Audio format must be provided or determinable from media type',\n      );\n    }\n\n    this.format = format;\n  }\n}\n\nexport class DefaultGeneratedAudioFileWithType extends DefaultGeneratedAudioFile {\n  readonly type = 'audio';\n\n  constructor(options: {\n    data: string | Uint8Array;\n    mediaType: string;\n    format: string;\n  }) {\n    super(options);\n  }","sourceCodeStart":27,"sourceCodeEnd":63,"githubUrl":"https://github.com/vercel/ai/blob/69428b1f8b037e4d118fb4853428d5c4e620493c/packages/ai/src/generate-speech/generated-audio-file.ts#L27-L63","documentation":"GeneratedAudioFile's constructor determines an audio format either from an explicitly provided `format` or by deriving it from the response media (content) type. If neither yields a format, a plain Error('Audio format must be provided or determinable from media type') is thrown. The source even notes this should become a proper AI SDK error class.","triggerScenarios":"Constructing GeneratedAudioFile manually with no `format` and no/unknown `mediaType` (e.g. 'application/octet-stream' or empty); wrapping raw bytes from a custom provider whose response lacks a Content-Type header.","commonSituations":"Custom/own provider implementations returning audio without a content-type header; proxies stripping headers; manual construction of GeneratedAudioFile in tests with only binary data.","solutions":["Pass an explicit `format` (e.g. 'mp3') when constructing GeneratedAudioFile","Make the custom provider return a proper audio Content-Type like 'audio/mpeg'","Map unknown media types to a known audio format before constructing the file"],"exampleFix":"// before\nnew GeneratedAudioFile({ data: bytes, mediaType: 'application/octet-stream' });\n// after\nnew GeneratedAudioFile({ data: bytes, mediaType: 'audio/mpeg', format: 'mp3' });","handlingStrategy":"validation","validationCode":"const AUDIO_TYPES = ['audio/mpeg','audio/wav','audio/aac','audio/opus','audio/flac'];\nif (!format && !(mediaType && AUDIO_TYPES.includes(mediaType))) {\n  throw new Error('Provide a format or a known audio media type');\n}","typeGuard":"function hasDeterminableFormat(f?: string, mt?: string): boolean {\n  return f != null || (mt?.startsWith('audio/') ?? false);\n}","tryCatchPattern":"try {\n  return new GeneratedAudioFile({ data, mediaType, format });\n} catch (e) {\n  if (e instanceof Error && e.message.includes('Audio format must be provided')) {\n    return new GeneratedAudioFile({ data, mediaType: 'audio/mpeg', format: 'mp3' });\n  }\n  throw e;\n}","preventionTips":["Always pass an explicit format when wrapping raw audio bytes","Ensure custom providers set audio Content-Type headers","Avoid proxies that strip response headers"],"tags":["audio","media-type","custom-provider"],"backgroundTag":"unknown-media-type","analyzedSha":"69428b1f8b037e4d118fb4853428d5c4e620493c","analyzedAt":"2026-08-30T12:32:21.016Z","schemaVersion":2},"datasetVersion":"2026-08-30T13:17:10.514Z"}