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

  1. Use a modern Chromium/Firefox/Safari release that ships Web Audio
  2. Serve the UI over HTTPS or localhost so secure-context restrictions do not apply
  3. If in an embedded webview, enable its media/audio runtime flags
  4. 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

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


AI-assisted analysis of mudler/LocalAI@44413a9d06 (2026-08-15). Data as JSON: /api/errors/88130c32fef316a5. Report an issue: GitHub.