mudler/LocalAI · error · Error
Web Audio API not available
Error message
Web Audio API not available
What it means
This error is printed by the cgo bridge in LocalAI's whisper backend when whisper_vad_detect_speech() (whisper.cpp Silero VAD) returns false for the submitted PCM buffer. whisper.cpp returns false from this call when the audio cannot be processed for speech detection — most commonly because the buffer is shorter than the minimum the VAD model accepts, because the global vctx was never initialized (load_model_vad not called or previously failed), or because the compute pass itself errored. It is a C-level integer return code surfaced through cgo, not a Go error value.
Source
Thrown at core/http/react-ui/src/hooks/useAudioPeaks.js:40
const [duration, setDuration] = useState(0)
const [error, setError] = useState(null)
const [loading, setLoading] = useState(false)
useEffect(() => {
setPeaks(null)
setDuration(0)
setError(null)
setLoading(false)
if (!src) return
let cancelled = false
setLoading(true)
async function decode() {
try {
const response = await fetch(src)
const buf = await response.arrayBuffer()
const ctx = getSharedAudioContext()
if (!ctx) throw new Error('Web Audio API not available')
const audioBuf = await ctx.decodeAudioData(buf.slice(0))
if (cancelled) return
const data = audioBuf.getChannelData(0)
const step = Math.max(1, Math.floor(data.length / buckets))
const result = new Float32Array(buckets)
for (let i = 0; i < buckets; i++) {
let peak = 0
const start = i * step
const end = Math.min(start + step, data.length)
for (let j = start; j < end; j++) {
const v = Math.abs(data[j])
if (v > peak) peak = v
}
result[i] = peak
}
setPeaks(result)
setDuration(audioBuf.duration)
setLoading(false)View on GitHub (pinned to 44413a9d06)
Solutions
- Check the audio length before calling vad(): whisper.cpp's Silero VAD requires a minimum buffer (>= 512 samples ≈ 32 ms per frame, and practically >= ~1 s for meaningful detection); buffer or concatenate short streaming chunks until you have at least ~0.5–1 s of 16 kHz mono PCM.
- Verify that load_model_vad() was called and returned 0 before vad(); inspect stderr for 'error: Failed to init model as VAD' — if present, the model path points at a non-VAD GGUF and must point at a Silero VAD model (e.g. silence-pc or silero VAD gguf).
- Confirm the PCM input is 16 kHz, mono, float32 normalized [-1,1]; re-run the pipeline with a known-good WAV file to isolate resampling bugs.
- Check the [ERROR]-prefixed ggml log lines (installed via whisper_log_set in the same file) immediately above this message — they name the underlying compute failure (backend load failure, OOM, unsupported tensor op); rebuild/re-run with CPU-only backends if a GPU backend is implicated.
- If whisper.cpp was recently updated, rebuild the gowhisper C++ shim against the matching headers so the whisper_vad_* ABI agrees with the vendored library.
Example fix
// Go caller: buffer short chunks before calling VAD
// before
segs, err := gw.VAD(chunk) // chunk may be 200 ms -> "error: failed to detect speech"
// after
const minVADSamples = 16000 // 1 s @ 16 kHz
buf = append(buf, chunk...)
if len(buf) < minVADSamples {
continue // keep accumulating audio
}
segs, err := gw.VAD(buf)
if err != nil {
log.Printf("vad failed (len=%d samples): %v", len(buf), err)
return err
} Defensive patterns
Strategy: validation
Validate before calling
// Run before calling vad(): minimum length, sample-rate, and init checks
const whisperSampleRate = 16000
const minVADSeconds = 1.0
func canRunVAD(sampleCount int, vadModelLoaded bool) error {
if !vadModelLoaded { // load_model_vad() must have returned 0
return errors.New("VAD model not loaded")
}
if sampleCount < int(minVADSeconds*whisperSampleRate) {
return fmt.Errorf("audio too short for VAD: %d samples (< %d)",
sampleCount, int(minVADSeconds*whisperSampleRate))
}
return nil
} Type guard
// Go: shape check on the PCM slice handed to cgo
func isVADReadyPCM(pcm []float32) bool {
return len(pcm) >= 16000 && // >= 1 s of 16 kHz mono
!hasNaN(pcm)
}
func hasNaN(pcm []float32) bool {
for _, s := range pcm {
if math.IsNaN(s) || math.Abs(s) > 1e3 { // not normalized float PCM
return true
}
}
return false
} Try / catch
// cgo has no exceptions: treat the integer return as the error
rc := C.vad((*C.float)(&pcm[0]), C.size_t(len(pcm)), &out, &outLen)
if rc == 1 {
// do NOT retry the same buffer; log length and model state, then
// drop or grow the buffer before the next attempt
log.Printf("vad failed: len=%d samples, vctxOK=%v", len(pcm), vctxOK)
} Prevention
- Buffer streaming audio to >= 1 s of 16 kHz mono float32 PCM before invoking VAD
- Verify load_model_vad() returned 0 (a real Silero-VAD GGUF) before the first vad() call
- Resample all input to 16 kHz mono and normalize to [-1,1] before the cgo boundary
- Log the ggml [ERROR] lines (already routed to stderr by ggml_log_cb) alongside the failure for root-cause triage
- Pin the whisper.cpp version and rebuild the gowhisper shim whenever the vendored dependency changes
When it happens
Trigger: Calling vad() with pcmf32_len below the Silero VAD minimum window (whisper.cpp rejects audio shorter than the model's minimum sample count, on the order of a few hundred ms at 16 kHz); calling vad() before a successful load_model_vad(), leaving the static vctx null (whisper.cpp then fails immediately); passing audio resampled to a rate other than 16 kHz mono float32; a ggml backend compute failure (e.g. incompatible GPU backend, out-of-memory) during the VAD forward pass; loading a regular transcription GGUF instead of a Silero-VAD GGUF would fail earlier at whisper_vad_init_from_file_with_params, but a truncated/corrupt VAD model can still init and then fail here.
Common situations: Users enabling LocalAI's VAD-based audio chunking and feeding very short clips (e.g. streaming chunks of 100–300 ms); forgetting to configure the VAD model path so the transcriber model is loaded but vctx is null; audio arriving stereo or 8 kHz because the upstream resampling step was skipped; whisper.cpp version drift between the vendored ggml/whisper sources and the prebuilt gowhisper library; GPU/CUDA or Metal backend failures on constrained hardware.
Related errors
- Web Audio API not available
- Normalized audio is larger than 50 MiB
- voiceCreate.audio.durationError
- model snapshot does not exist: {model_ref}
- model snapshot must contain exactly one {suffix} file; found
AI-assisted analysis of mudler/LocalAI@44413a9d06 (2026-08-15).
Data as JSON: /api/errors/ee67a33f05d057c7.
Report an issue: GitHub.