moeru-ai/airi · warning
Web Speech API recognition did not start immediately. This m
Error message
Web Speech API recognition did not start immediately. This might be due to:
What it means
First line of a multi-line console.warn block in the browser Web Speech API transcription provider. startRecognition() wraps recognition.start() and returns false when the call throws - most often an InvalidStateError (already started) or a permission/security failure. The provider deliberately does not retry: the SpeechRecognition instance stays created so a later start can succeed once microphone permission or a user gesture is available.
Source
Thrown at packages/stage-ui/src/libs/providers/providers/browser-web-speech-api/provider.ts:457
}
recognition.onsoundend = () => {
console.info('Web Speech API sound ended')
}
recognition.onaudioend = () => {
console.info('Web Speech API audio capture ended')
}
recognition.onnomatch = () => {
console.info('Web Speech API: No speech match')
}
const started = startRecognition()
if (!started) {
// If immediate start failed, it might be a permission issue
// Web Speech API will prompt for permission automatically, so we just log
console.warn('Web Speech API recognition did not start immediately. This might be due to:')
console.warn('1. Microphone permission not granted - browser should prompt automatically')
console.warn('2. Recognition already running - this is normal if called multiple times')
console.warn('3. Browser requires user gesture - ensure microphone was enabled by user action')
// Don't retry immediately - wait for permission or user action
// The recognition instance is already created, so it can be started later if needed
}
return {
fullStream,
text: deferredText.promise,
textStream,
recognition: recognitionInstance,
}
}
View on GitHub (pinned to 677329427f)
Solutions
- Check the site's microphone permission and grant it, then trigger recognition again
- Start recognition from a user interaction (button click) on first enable so gesture requirements are satisfied
- Track running state via onstart/onend to avoid calling start() on an active recognition (InvalidStateError)
- Confirm window.SpeechRecognition or window.webkitSpeechRecognition exists before selecting this provider (Firefox lacks it)
- In Electron, allow 'media' via session.setPermissionRequestHandler so the renderer can use the API
Example fix
// before: recognition started automatically on mount
startRecognition()
// after: gate the first start behind a user gesture, tolerate double start
button.onclick = () => {
try {
recognition.start()
}
catch {
// InvalidStateError: recognition already running - safe to ignore
}
} Defensive patterns
Strategy: validation
Validate before calling
const SR = window.SpeechRecognition ?? window.webkitSpeechRecognition
if (!SR)
throw new Error('SpeechRecognition is not supported in this browser')
const perm = await navigator.permissions?.query({ name: 'microphone' as PermissionName })
if (perm && perm.state === 'denied')
throw new Error('Microphone permission denied') Type guard
function isSpeechRecognitionSupported(): boolean {
return typeof window !== 'undefined'
&& Boolean(window.SpeechRecognition ?? window.webkitSpeechRecognition)
} Try / catch
recognition.onerror = (event) => {
if (event.error === 'not-allowed' || event.error === 'service-not-allowed')
promptForMicrophonePermission()
}
try {
recognition.start()
}
catch {
// InvalidStateError: already running - safe to ignore
} Prevention
- Gate the first recognition.start() behind a user gesture
- Track running state via onstart/onend to avoid double starts
- Pre-check microphone permission with navigator.permissions.query
- Offer a local whisper provider as fallback where Web Speech API is unavailable (Firefox)
When it happens
Trigger: Calling the provider's transcription entry while a SpeechRecognition instance is already running (double start), starting without microphone permission granted, starting outside a user gesture in browsers that require one, or running in a browser without window.SpeechRecognition / window.webkitSpeechRecognition. startRecognition() returns false and this warn block prints.
Common situations: First-run microphone prompt still pending; permission previously denied; Electron renderer without a user-gesture context; Chrome's speech service wedged after many restarts; iOS Safari gesture restrictions.
Related errors
- Web Speech API error:
- Web Speech API recognition start failed:
- 1. Microphone permission not granted - browser should prompt
- 2. Recognition already running - this is normal if called mu
- 3. Browser requires user gesture - ensure microphone was ena
AI-assisted analysis of moeru-ai/airi@677329427f (2026-08-18).
Data as JSON: /api/errors/60297f6d8393403e.
Report an issue: GitHub.