moeru-ai/airi · error · Error
No audio track available in the stream
Error message
No audio track available in the stream
What it means
In the Web branch of the beat-sync detector (packages/stage-shared/src/beat-sync/detector.ts:138), audio is captured via navigator.mediaDevices.getDisplayMedia with echoCancellation/noiseSuppression/autoGainControl disabled. If the returned MediaStream has zero audio tracks, this error is thrown: the user shared a surface but no audio came with it, so there is nothing for the analyser to read.
Solutions
- Re-run getDisplayMedia and instruct the user to pick a Screen/Tab surface AND tick the share-audio checkbox
- Catch this error and fall back to microphone input via getUserMedia({ audio: true })
- Pre-check browser support and surface an explicit 'enable audio sharing' hint in the UI
Example fix
// before
const stream = await navigator.mediaDevices.getDisplayMedia({ audio: { echoCancellation: false }, video: true })
if (stream.getAudioTracks().length === 0) throw new Error('No audio track available in the stream')
// after
let stream = await navigator.mediaDevices.getDisplayMedia({ audio: { echoCancellation: false }, video: true })
if (stream.getAudioTracks().length === 0) {
stream = await navigator.mediaDevices.getUserMedia({ audio: true }) // mic fallback
} Defensive patterns
Strategy: fallback
Validate before calling
const stream = await navigator.mediaDevices.getDisplayMedia({ audio: { echoCancellation: false, noiseSuppression: false, autoGainControl: false }, video: true })
if (stream.getAudioTracks().length === 0) {
// prompt user to retry with audio, or fall back before the detector throws
stream.getTracks().forEach(t => t.stop())
stream = await navigator.mediaDevices.getUserMedia({ audio: true })
} Type guard
const hasAudioTrack = (stream: MediaStream): boolean => stream.getAudioTracks().length > 0
Try / catch
try {
await startBeatSync({ env: StageEnvironment.Web })
}
catch (error) {
if (error instanceof Error && error.message === 'No audio track available in the stream') {
showHint('Tick the share-audio checkbox when picking a screen or tab.')
return
}
throw error
} Prevention
- Tell users to pick Screen/Tab AND enable audio sharing in the picker
- Check getAudioTracks().length immediately after getDisplayMedia
- Offer microphone input as a documented fallback source
When it happens
Trigger: User selects a window in the Chrome screen picker (window capture never carries audio), the 'Share tab audio/system audio' checkbox is left unchecked, or a browser/Firefox configuration where display capture exposes no audio track.
Common situations: Music-visualization features that beat-sync from Spotify/YouTube in another tab while the user skips the audio checkbox; kiosk setups; browsers without system-audio capture.
Related errors
- Failed to initialize voice activity detection.
- 1. Microphone permission not granted - browser should…
- 1. Microphone permission not granted - browser should…
- 2. Recognition already running - this is normal if called…
- Beat Sync is not available in Stage Pocket
AI-assisted analysis of moeru-ai/airi@677329427f (2026-08-18).
Data as JSON: /api/errors/bc590306965a3b2f.
Report an issue: GitHub.
Appendix: source
Thrown at packages/stage-shared/src/beat-sync/detector.ts:138
const updateParameters = (params: Partial<AnalyserWorkletParameters>) => {
analyser?.updateParameters(params)
}
const startScreenCapture = async () => start(async (ctx) => {
switch (options.env) {
case StageEnvironment.Web: {
const stream = await navigator.mediaDevices.getDisplayMedia({
audio: {
echoCancellation: false,
noiseSuppression: false,
autoGainControl: false,
},
video: true,
})
if (stream.getAudioTracks().length === 0) {
throw new Error('No audio track available in the stream')
}
stream.getAudioTracks().forEach((track) => {
let stopCalled = false
track.addEventListener('ended', () => {
if (stopCalled)
return
stopCalled = true
stop()
})
})
const node = ctx.createMediaStreamSource(stream)
stopSource = () => {
stream.getTracks().forEach(track => track.stop())
}
return nodeView on GitHub (pinned to 677329427f)