{"record":{"id":"d20c6e494256c92e","repo":"moeru-ai/airi","slug":"no-audio-file-provided-for-transcription","errorCode":null,"errorMessage":"No audio file provided for transcription.","messagePattern":"No audio file provided for transcription\\.","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"packages/provider-inference/src/providers/cloud/mimo-audio/index.ts","lineNumber":174,"sourceCode":"  for (const byte of bytes)\n    binary += String.fromCharCode(byte)\n\n  return `data:${file.type || 'audio/wav'};base64,${btoa(binary)}`\n}\n\nfunction createMimoTranscriptionProvider(config: MimoTranscriptionConfig) {\n  const apiKey = config.apiKey?.trim() ?? ''\n  const baseUrl = normalizeBaseUrl(config.baseUrl)\n  const defaultModel = config.model || 'mimo-v2-omni'\n\n  return {\n    transcription: (model: string) => ({\n      baseURL: baseUrl,\n      model: model || defaultModel,\n      headers: {},\n      fetch: async (_input: RequestInfo | URL, init?: RequestInit) => {\n        if (!(init?.body instanceof FormData))\n          throw new Error('No audio file provided for transcription.')\n\n        const file = init.body.get('file')\n        if (!(file instanceof Blob))\n          throw new Error('No audio file provided for transcription.')\n\n        const modelName = String(init.body.get('model') || defaultModel)\n        const dataUri = await readBlobAsDataUri(file)\n        const base64Data = dataUri.split(',')[1]\n        const response = await fetch(new URL('chat/completions', baseUrl), {\n          method: 'POST',\n          headers: { 'Content-Type': 'application/json', 'api-key': apiKey },\n          body: JSON.stringify({\n            model: modelName,\n            messages: [{\n              role: 'user',\n              content: [\n                { type: 'text', text: 'Transcribe the audio content.' },\n                { type: 'input_audio', input_audio: { data: base64Data, format: audioFormatFromDataUri(dataUri) } },","sourceCodeStart":156,"sourceCodeEnd":192,"githubUrl":"https://github.com/moeru-ai/airi/blob/f679616c34f1cf6d282c8d64264242af944b3fed/packages/provider-inference/src/providers/cloud/mimo-audio/index.ts#L156-L192","documentation":"The MiMo transcription provider wraps xsAI-style speech transcription by intercepting the fetch call. The adapter expects the SDK to issue the request as a FormData body containing an audio file under the 'file' key. When the body is not FormData at all, this error is thrown to signal that no audio was supplied to the transcription call.","triggerScenarios":"Calling provider.transcription(model) and issuing a request whose init.body is not a FormData instance — e.g. a string body, JSON body, undefined body, or a fetch call made directly against the baseURL without multipart encoding.","commonSituations":"Consumers bypass the SDK's transcription helper and call fetch manually with JSON; a custom HTTP client or middleware strips or replaces the FormData body; using a runtime where the xsAI SDK serializes the request differently than expected; passing audio incorrectly so the SDK sends a plain object.","solutions":["Pass the audio via the SDK's transcription API with a File/Blob so it is encoded as multipart FormData under the 'file' field.","Verify no middleware or wrapper replaces init.body with a string or object before the provider fetch runs.","If calling fetch manually, construct FormData with fields 'file' (Blob) and 'model' and pass it as init.body.","Ensure the input is actually audio (Blob/File), not a URL string or base64 string."],"exampleFix":"// before\nawait provider.transcription('mimo-audio').do({ input: audioBase64 })\n// after\nconst form = new FormData()\nform.append('file', audioFile, 'audio.wav')\nform.append('model', 'mimo-audio')\nawait fetch(url, { method: 'POST', body: form })","handlingStrategy":"validation","validationCode":"if (!(audio instanceof Blob)) throw new TypeError('transcription requires a Blob audio file')\nconst form = new FormData()\nform.append('file', audio, 'audio.wav')","typeGuard":"const isBlob = (v: unknown): v is Blob => typeof Blob !== 'undefined' && v instanceof Blob","tryCatchPattern":"try { await transcribe(audio) } catch (e) { if (e.message.includes('No audio file provided')) { /* rebuild FormData with Blob under 'file' */ } else throw e }","preventionTips":["Always pass a real File/Blob, never a path or base64 string","Use the SDK's transcription helper rather than manual fetch","Keep field name 'file' in FormData","Test middleware doesn't rewrite the request body"],"tags":["audio","transcription","request-body","validation"],"backgroundTag":"missing-required-argument","analyzedSha":"f679616c34f1cf6d282c8d64264242af944b3fed","analyzedAt":"2026-09-08T13:18:15.005Z","contentChangedAt":"2026-09-08T13:18:15.005Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}