{"record":{"id":"8d01c823842bd0cc","repo":"mudler/LocalAI","slug":"normalized-audio-is-larger-than-50-mib","errorCode":null,"errorMessage":"Normalized audio is larger than 50 MiB","messagePattern":"Normalized audio is larger than 50 MiB","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"warning","filePath":"core/http/react-ui/src/pages/VoiceProfileCreate.jsx","lineNumber":32,"sourceCode":"\nfunction base64ToArrayBuffer(value) {\n  const binary = window.atob(value)\n  const bytes = new Uint8Array(binary.length)\n  for (let index = 0; index < binary.length; index += 1) bytes[index] = binary.charCodeAt(index)\n  return bytes.buffer\n}\n\nasync function normalizeAudioSample(sample) {\n  const source = sample.blob?.arrayBuffer\n    ? await sample.blob.arrayBuffer()\n    : base64ToArrayBuffer(sample.base64)\n  const AudioCtx = window.AudioContext || window.webkitAudioContext\n  if (!AudioCtx) throw new Error('Web Audio API is not available in this browser')\n  const context = new AudioCtx()\n  try {\n    const decoded = await context.decodeAudioData(source.slice(0))\n    const blob = audioBufferToWavBlob(decoded, REFERENCE_SAMPLE_RATE)\n    if (blob.size > MAX_AUDIO_BYTES) throw new Error('Normalized audio is larger than 50 MiB')\n    return {\n      ...sample,\n      blob,\n      dataUrl: URL.createObjectURL(blob),\n      objectUrl: true,\n      mime: 'audio/wav',\n      duration: decoded.duration,\n      sampleRate: REFERENCE_SAMPLE_RATE,\n      name: sample.name || 'recording.wav',\n    }\n  } finally {\n    await context.close().catch(() => {})\n  }\n}\n\nfunction ReadinessItem({ ready, warning, children }) {\n  const tone = ready ? 'ready' : warning ? 'warning' : 'pending'\n  return (","sourceCodeStart":14,"sourceCodeEnd":50,"githubUrl":"https://github.com/mudler/LocalAI/blob/44413a9d06bf5bc52ce088ba8ca74e5a2e8bee26/core/http/react-ui/src/pages/VoiceProfileCreate.jsx#L14-L50","documentation":"Thrown by normalizeAudioSample() after successful decode when the resampled WAV blob produced by audioBufferToWavBlob(decoded, REFERENCE_SAMPLE_RATE) exceeds MAX_AUDIO_BYTES (50 MiB). PCM WAV size is duration × sampleRate × channels × 2 bytes, so long or multi-channel audio decoded and resampled to the reference rate can blow past the cap.","triggerScenarios":"Uploading a very long recording (the UI separately enforces 1–120 s after normalization, so this mostly fires for high-channel-count or high-rate sources before the duration check), or a decoded file whose channel layout expands after resampling (e.g. 5.1 surround decoded to many channels).","commonSituations":"User drags a long audio file (podcast excerpt) instead of a short voice sample; stereo/surround source decoded with channel expansion; sample already at a higher rate than REFERENCE_SAMPLE_RATE with long duration.","solutions":["Trim the sample to under 120 s (and ideally well under) before uploading","Downmix to mono / standard rate in an external tool if the source is multi-channel","Retry with a shorter, plain voice recording — the duration check would reject long audio anyway"],"exampleFix":null,"handlingStrategy":"validation","validationCode":"// Estimate decoded size before normalizing: PCM bytes ≈ duration × rate × channels × 2\nfunction estimatedWavBytes(durationSeconds, channels = 1, rate = REFERENCE_SAMPLE_RATE) {\n  return durationSeconds * rate * channels * 2 + 44 /* header */\n}","typeGuard":null,"tryCatchPattern":"try {\n  const normalized = await normalizeAudioSample(sample)\n} catch (err) {\n  if (err.message.includes('larger than 50 MiB')) {\n    setAudioError('Sample too large after conversion — trim it to under 2 minutes, mono')\n    return\n  }\n  throw err\n}","preventionTips":["Enforce a client-side duration cap before normalization (the flow already rejects >120 s after)","Prefer mono recordings — channel count multiplies WAV size","Remember the 50 MiB cap applies post-resampling at REFERENCE_SAMPLE_RATE, not to the original file size"],"tags":["audio","size-limit","voice","react-ui"],"backgroundTag":null,"analyzedSha":"44413a9d06bf5bc52ce088ba8ca74e5a2e8bee26","analyzedAt":"2026-08-15T10:13:50.291Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}