jitsi/jitsi-meet · error · Error
NoAudioTrackFound
Error message
NoAudioTrackFound
What it means
After a display-media stream is obtained for local recording, the code expects at least one audio track in the gdmStream (the tab audio shared via getDisplayMedia). If the user shared the tab without audio (didn't tick 'Share tab audio' / 'Share system audio'), getAudioTracks() is empty and 'NoAudioTrackFound' is thrown before the audio mixer is fed.
Source
Thrown at react/features/recording/components/Recording/LocalRecordingManager.web.ts:233
const gdmVideoTrack = gdmStream.getVideoTracks()[0];
if (supportsCaptureHandle) {
const isBrowser = gdmVideoTrack.getSettings().displaySurface === 'browser';
const matchesHandle = (supportsCaptureHandle // @ts-ignore
&& gdmVideoTrack.getCaptureHandle()?.handle === `JitsiMeet-${tabId}`);
if (!isBrowser || !matchesHandle) {
gdmStream.getTracks().forEach((track: MediaStreamTrack) => track.stop());
throw new Error('WrongSurfaceSelected');
}
}
this.initializeAudioMixer();
const gdmAudioTrack = gdmStream.getAudioTracks()[0];
if (!gdmAudioTrack) {
throw new Error('NoAudioTrackFound');
}
this.addAudioTrackToLocalRecording(gdmAudioTrack);
const localAudioTrack = getLocalTrack(tracks, MEDIA_TYPE.AUDIO)?.jitsiTrack?.track;
if (localAudioTrack) {
this.addAudioTrackToLocalRecording(localAudioTrack);
}
this.stream = new MediaStream([
...this.audioDestination?.stream.getAudioTracks() || [],
gdmVideoTrack
]);
}
this.recorder = new MediaRecorder(this.stream, {
// @ts-ignoreView on GitHub (pinned to 98de6219cc)
Solutions
- Prompt the user to enable 'Share audio' / 'Share tab audio' when the picker opens, and catch this error to show that instruction and retry
- Request audio explicitly in getDisplayMedia constraints (audio: true with preferCurrentTab) so the picker defaults audio on
- Validate gdmStream.getAudioTracks().length before proceeding and fall back to mic-only recording if acceptable
- On unsupported configurations, surface a clear notification that tab audio sharing is required for local recording
Example fix
// before
const gdmAudioTrack = gdmStream.getAudioTracks()[0];
if (!gdmAudioTrack) {
throw new Error('NoAudioTrackFound');
}
// after
const gdmAudioTrack = gdmStream.getAudioTracks()[0];
if (!gdmAudioTrack) {
dispatch(showErrorNotification({
titleKey: 'localRecording.noAudio',
descriptionKey: 'localRecording.shareTabAudio'
}, NOTIFICATION_TIMEOUT_TYPE.MEDIUM));
gdmStream.getTracks().forEach(t => t.stop());
return;
} Defensive patterns
Strategy: validation
Validate before calling
const gdmStream = await navigator.mediaDevices.getDisplayMedia({
video: true,
audio: true, // ask for tab audio up front
preferCurrentTab: true
});
if (gdmStream.getAudioTracks().length === 0) {
// tell user to tick 'Share tab audio' and retry instead of proceeding
} Type guard
const hasSharedAudio = (s: MediaStream): boolean => s.getAudioTracks().length > 0;
Try / catch
try {
await manager.startLocalRecording();
} catch (e: unknown) {
if (e instanceof Error && e.message === 'NoAudioTrackFound') {
showError('Enable \'Share tab audio\' in the sharing dialog and try again.');
} else {
throw e;
}
} Prevention
- Always request audio: true in getDisplayMedia constraints
- Instruct users to check the 'share audio' checkbox before confirming
- Validate getAudioTracks().length immediately after the picker resolves
When it happens
Trigger: Calling startLocalRecording after getDisplayMedia succeeded but the user did not enable audio sharing in the picker, or the browser/policy stripped the audio track (e.g. some Linux setups, or displaySurface configurations that don't offer tab audio).
Common situations: User forgets to check 'Share tab audio' in Chrome's dialog; browser variant that doesn't expose tab audio; enterprise policy disabling display audio capture; expecting mic audio to substitute for gdm audio.
Related errors
AI-assisted analysis of jitsi/jitsi-meet@98de6219cc (2026-08-28).
Data as JSON: /api/errors/e222fbd9e2481b3f.
Report an issue: GitHub.