Huddle mediaDevices access crashes the whole app when navigator.mediaDevices is undefined
- Dominant language
- Rust
- Stars
- 32.7k
- Forks
- 4.3k
- Avg merge
- 1d 13h
- Merged PRs (30d)
- 253
Description
## Summary
In a WKWebView running in a non-secure context, `navigator.mediaDevices` is `undefined`. The huddle code accesses it unguarded in mount-time effects, so the entire React tree crashes to the "Something went wrong" error boundary with:
```
undefined is not an object (evaluating 'navigator.mediaDevices.enumerateDevices')
```
## Where (v0.4.26, `a31fc4d2`)
Unguarded, and reached from `useEffect` on mount (i.e. crashes without the user ever starting a huddle):
- `desktop/src/features/huddle/lib/useAudioDevices.ts:20` — `navigator.mediaDevices.enumerateDevices()`, plus `addEventListener` / `removeEventListener` at :30 / :32
- `desktop/src/features/huddle/HuddleContext.tsx:168` / `:173` — `navigator.mediaDevices.addEventListener` / `removeEventListener` (output-device effect)
- `desktop/src/features/huddle/HuddleContext.tsx:374` — `navigator.mediaDevices.getUserMedia` (huddle-join path; crashes on join rather than on mount)
## Prior art in the codebase
The profile avatar path already guards this exact pattern:
`desktop/src/features/profile/lib/animatedAvatarCapture.ts:128` — `if (!navigator.mediaDevices?.enumerateDevices) return [];`
So the huddle paths are just inconsistent with the app's own established convention. (Note `getUserMedia` at `animatedAvatarCapture.ts:154` is likewise unguarded, if you want to standardize across both features.)
## Repro
Run the desktop app in a WKWebView context where `navigator.mediaDevices` is unavailable (e.g. a non-secure-context webview). On mount of the huddle context, the app crashes to the error boundary.
## Suggested fix
Guard the huddle `mediaDevices` accesses the same way the avatar code does — degrade to an empty device list / skip listener registration rather than throw. The mount-time effects should no-op when `navigator.mediaDevices?.enumerateDevices` is absent; the `getUserMedia` join path should surface a clear "microphone unavailable" error instead of the opaque crash. Happy to open a PR.
Contributor guide
Research direction
Start with desktop/src/features/huddle/lib/useAudioDevices.ts and the mediaDevices effects in desktop/src/features/huddle/HuddleContext.tsx, then compare desktop/src/features/profile/lib/animatedAvatarCapture.ts:128. Verify the mount-time effects no-op when mediaDevices is unavailable and the join path reports a clear microphone-unavailable error instead of crashing.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- react, typescript
- Domain
- desktop, frontend
- Issue type
- Bug
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Activity status
- Quiet
- Clarity
- Clearly specified
- Newbie friendliness
- 72/100