mudler/LocalAI · error · Error
Web Audio API is not available in this browser
Error message
Web Audio API is not available in this browser
What it means
Thrown by normalizeAudioSample() when neither window.AudioContext nor window.webkitAudioContext exists, so the recorded/uploaded voice sample cannot be decoded and resampled. The function needs decodeAudioData to convert the source (Blob via arrayBuffer, or base64 via atob) into a WAV blob at REFERENCE_SAMPLE_RATE before upload.
Source
Thrown at core/http/react-ui/src/pages/VoiceProfileCreate.jsx:27
import { audioBufferToWavBlob } from '../hooks/useMediaCapture'
import { voiceProfilesApi } from '../utils/api'
const MAX_AUDIO_BYTES = 50 * 1024 * 1024
const REFERENCE_SAMPLE_RATE = 24000
function base64ToArrayBuffer(value) {
const binary = window.atob(value)
const bytes = new Uint8Array(binary.length)
for (let index = 0; index < binary.length; index += 1) bytes[index] = binary.charCodeAt(index)
return bytes.buffer
}
async function normalizeAudioSample(sample) {
const source = sample.blob?.arrayBuffer
? await sample.blob.arrayBuffer()
: base64ToArrayBuffer(sample.base64)
const AudioCtx = window.AudioContext || window.webkitAudioContext
if (!AudioCtx) throw new Error('Web Audio API is not available in this browser')
const context = new AudioCtx()
try {
const decoded = await context.decodeAudioData(source.slice(0))
const blob = audioBufferToWavBlob(decoded, REFERENCE_SAMPLE_RATE)
if (blob.size > MAX_AUDIO_BYTES) throw new Error('Normalized audio is larger than 50 MiB')
return {
...sample,
blob,
dataUrl: URL.createObjectURL(blob),
objectUrl: true,
mime: 'audio/wav',
duration: decoded.duration,
sampleRate: REFERENCE_SAMPLE_RATE,
name: sample.name || 'recording.wav',
}
} finally {
await context.close().catch(() => {})
}View on GitHub (pinned to 44413a9d06)
Solutions
- Use a modern Chromium/Firefox/Safari release that ships Web Audio
- Serve the UI over HTTPS or localhost so secure-context restrictions do not apply
- If in an embedded webview, enable its media/audio runtime flags
- As a fallback, pre-convert the sample to 16 kHz mono WAV externally and upload where normalization is bypassed (if the flow allows)
Defensive patterns
Strategy: type-guard
Validate before calling
// Feature-detect before entering the voice-profile flow
export function webAudioAvailable() {
return Boolean(window.AudioContext || window.webkitAudioContext)
} Type guard
function supportsWebAudio() {
return typeof window !== 'undefined' && Boolean(window.AudioContext || window.webkitAudioContext)
} Try / catch
try {
const normalized = await normalizeAudioSample(sample)
} catch (err) {
if (err.message.includes('Web Audio API')) {
setUnsupportedBanner('Voice profiles require a browser with Web Audio support')
return // disable the flow instead of showing a raw error
}
throw err
} Prevention
- Gate the voice-profile UI on supportsWebAudio() and show a requirements notice instead of an error
- Serve over HTTPS/localhost so secure-context restrictions do not hide AudioContext
- Test in the oldest webview you support before shipping the feature
When it happens
Trigger: Running the voice-profile creation flow in a browser with Web Audio disabled or unavailable: very old browsers, embedded webviews, browsers with strict audio-protection flags, or non-secure contexts where AudioContext is restricted.
Common situations: Opening the UI in a legacy/embedded webview (Electron without audio support, old Android WebView); accessing the UI over plain HTTP from a browser that gates AudioContext behind secure contexts; enterprise policy disabling Web Audio.
Related errors
- Normalized audio is larger than 50 MiB
- HTTP ${response.status}
- No job ID returned from server
- status: HTTP ${statusRes.status}
- unknown error
AI-assisted analysis of mudler/LocalAI@44413a9d06 (2026-08-15).
Data as JSON: /api/errors/88130c32fef316a5.
Report an issue: GitHub.