Capture Audio Fails With "Missing audio recording permissions."
Metadata
- Date:
2026-04-03 - Status:
fixed - Severity:
high - Related issue/ticket:
N/A - Owner:
N/A
About
Overview: - During capture start, audio initialization fails with capture_audio_failed {"error": "Missing audio recording permissions."}. - This bug is important because session audio is not recorded/uploaded, reducing multimodal capture quality.
Technical Questions: - Assumption validated: this error signature is Android-specific in expo-av (E_MISSING_PERMISSION). - Bug age appears to match the migration to JS-side AudioRecorder where permission request logic was omitted. - Obvious miss: AudioRecorder.start() did not call Audio.getPermissionsAsync() / Audio.requestPermissionsAsync(). - Repro state: Android device path with SDK available and capture start invoking audio setup.
Resources: - Runtime log excerpt from user report in current debugging thread. - main/app/lib/capture-session.ts - main/app/lib/audio-recorder.ts - main/app/app.json - main/app/android/app/src/main/AndroidManifest.xml - main/app/__tests__/audio-recorder.test.ts
Steps to cause failure
flowchart LR
StartCapture --> StartAudio["AudioRecorder.start()"]
StartAudio --> NoPermissionCheck["No explicit permission request"]
NoPermissionCheck --> Prepare["prepareToRecordAsync()"]
Prepare --> MissingPerm["E_MISSING_PERMISSION"]
MissingPerm --> CaptureAudioFailed["capture_audio_failed logged"] System
flowchart TD
CaptureSession --> AudioRecorder
AudioRecorder --> ExpoAV
ExpoAV --> AndroidPerms
AndroidPerms --> ManifestAndRuntime
ManifestAndRuntime --> CaptureLogs Notes about the system can go here.
Reproduction Details
- Start capture on Android in SDK-available mode.
- Observe
capture_audio_starting. - Observe
capture_audio_failedwithMissing audio recording permissions.and nocapture_audio_started.
Reproduction test (unit preferred): npm test -- audio-recorder.test.ts --runInBand
Notes for PR
Root cause: - Runtime microphone permission was never requested in AudioRecorder.start(). - Android app config permissions omitted RECORD_AUDIO, so permission could not be granted in normal flow.
Fix summary: - Added explicit permission check/request in AudioRecorder.start() and fail-fast error when denied. - Added regression tests for permission-request and denied-permission paths. - Added RECORD_AUDIO to Expo Android permissions and added expo-av plugin microphone usage string for iOS prompt text.
Verification summary: - Pre-fix reproduction test failed (start requests audio permission... expected call count > 0, got 0). - Post-fix test suites pass for audio-recorder and capture-session.
Audit Log
| ID | Action | Note | Context |
|---|---|---|---|
| 1 | Create audit log | Initialize bug investigation | issue created |
| 2 | Trace logs to source | Confirmed Missing audio recording permissions. originates from expo-av Android path | root-cause analysis |
| 3 | Add failing unit test | Added permission-request assertion in audio-recorder tests and confirmed it fails pre-fix | reproduction harness |
| 4 | Fix recorder permission flow | Added getPermissionsAsync + requestPermissionsAsync gate in AudioRecorder.start() | source fix |
| 5 | Fix app permission config | Added Android RECORD_AUDIO in Expo config and microphone permission prompt config for iOS | config fix |
| 6 | Verify with tests | audio-recorder.test.ts and capture-session.test.ts pass after fix | validation |
| 7 | Code-review gate | Checked plan alignment and test coverage for modified flow paths | final check |
Verification
- [x] Reproduced failure before fix
- [x] Reproduction test fails before fix
- [x] Root cause identified with evidence
- [x] Fix applied at source (no workaround-only patch)
- [x] Reproduction test passes after fix
- [x] Reproduction path now passes
- [x] Regression test added/updated (or
N/Awith reason) - [x] Verified no duplicate solved-bug log exists for same root cause