moeru-ai/airi · warning
No audio stream available
Error message
No audio stream available
What it means
Second guard in setupAudioMonitoring(): after the device check passes, the hearing store's startStream() is awaited and stream.value verified. If no MediaStream materialized - getUserMedia denied, no audio hardware, insecure context, or the store failed to acquire the mic - the function warns and returns false, so monitoring never starts.
Source
Thrown at packages/stage-pages/src/pages/settings/modules/hearing.vue:154
if (useVADModel.value && loadedVAD.value) {
return isSpeechVAD.value
}
return isSpeechVolume.value
})
async function setupAudioMonitoring() {
try {
if (!selectedAudioInput.value) {
console.warn('No audio input device selected')
return false
}
await stopAudioMonitoring()
await startStream()
if (!stream.value) {
console.warn('No audio stream available')
return false
}
if (supportsStreamInput.value) {
// The Hearing pipeline owns speech segmentation and the provider session.
// The page VAD below only drives the visualization for streaming providers.
await transcribeForMediaStream(stream.value, {
consumerId: hearingPlaygroundTranscriptionConsumerId,
onSpeechEnd: finishStreaming,
onTranscriptionUpdate: replaceStreamingText,
})
}
const source = audioContext.value.createMediaStreamSource(stream.value)
// Fallback speaking detection (when VAD model is not used)
const analyzer = startAnalyzer(audioContext.value)
onAnalyzerUpdate((volumeLevel) => {View on GitHub (pinned to 677329427f)
Solutions
- Grant microphone permission for the origin and retry setup
- Serve over HTTPS or localhost - getUserMedia requires a secure context
- Verify a microphone exists and is enabled at the OS level
- Avoid racing setup with stopAudioMonitoring; serialize start/stop toggles
- Look for the preceding console error from startStream/getUserMedia - the DOMException name (NotAllowedError, NotFoundError, NotReadableError) identifies the cause
Example fix
// before
await startStream()
if (!stream.value) {
console.warn('No audio stream available')
return false
}
// after - surface the real acquisition failure and validate tracks
try {
await startStream()
}
catch (err) {
console.error('getUserMedia failed:', (err as DOMException).name)
return false
}
if (!stream.value || stream.value.getAudioTracks().length === 0)
return false Defensive patterns
Strategy: validation
Validate before calling
if (!window.isSecureContext)
throw new Error('Microphone access requires HTTPS or localhost')
const perm = await navigator.permissions.query({ name: 'microphone' as PermissionName })
if (perm.state === 'denied')
throw new Error('Microphone permission denied')
await startStream()
if (!stream.value || stream.value.getAudioTracks().length === 0)
return false Try / catch
try {
await startStream()
}
catch (err) {
const name = (err as DOMException).name
if (name === 'NotAllowedError') showPermissionUI()
else if (name === 'NotFoundError') showNoDeviceUI()
else throw err
return false
} Prevention
- Serve over HTTPS or localhost for getUserMedia
- Ask permission early (onboarding) so streams acquire on first try
- Serialize start/stop toggles to avoid tearing down a stream mid-setup
- Check stream.value.getAudioTracks().length, not just stream existence
When it happens
Trigger: getUserMedia rejects (NotAllowedError after denial, NotFoundError without hardware); page served over plain http (not localhost) where getUserMedia is unavailable; stream acquired but immediately torn down by a concurrent stopAudioMonitoring; OS-level exclusive mic lock by another application.
Common situations: Permission denied then retry; dev server accessed over http on a non-localhost host; VMs without audio devices; race between toggling monitoring off and on rapidly.
Related errors
- No microphone stream available for voice input
- AudioContext not initialized
- checkMacOSScreenCapturePermission is only available on macOS
- requestMacOSScreenCapturePermission is only available on mac
- Permission denied: ${details.area}.${details.action} "${deta
AI-assisted analysis of moeru-ai/airi@677329427f (2026-08-18).
Data as JSON: /api/errors/5ca1ce2f1521cf0b.
Report an issue: GitHub.