different-ai/openwork · error
macOS denied microphone access. Enable OpenWork in System Se
Error message
macOS denied microphone access. Enable OpenWork in System Settings > Privacy & Security > Microphone, then restart OpenWork.
What it means
On macOS the panel first calls requestMacMicrophoneAccess() to trigger the OS microphone permission prompt. If macOS denies the permission (user clicked Den, or the app is blocked at the OS level), getUserMedia would fail anyway, so the panel throws with instructions pointing at System Settings.
Source
Thrown at apps/app/src/react-app/domains/session/voice/voice-panel.tsx:496
}
}, [addEntry, props.sessionId, requestRealtimeResponse, setRuntimeStatus]);
const connectRealtime = useCallback(async (audioInput = true) => {
const client = props.client;
if (!client) throw new Error("OpenWork host connection is not ready.");
if (audioInput && !navigator.mediaDevices?.getUserMedia) throw new Error("Microphone capture is unavailable in this runtime.");
disconnectRealtime(true);
setRuntimeStatus("connecting", "Minting Realtime session...");
const sessionContext = await loadVoiceSessionContext(props.opencodeBaseUrl, props.openworkToken, props.sessionId);
const realtimeSession = await client.createVoiceRealtimeSession({ sessionContext });
const peer = new RTCPeerConnection();
voiceRealtime.peer = peer;
if (audioInput) {
setRuntimeStatus("connecting", "Requesting microphone...");
const macPermissionGranted = await requestMacMicrophoneAccess();
if (!macPermissionGranted) throw new Error("macOS denied microphone access. Enable OpenWork in System Settings > Privacy & Security > Microphone, then restart OpenWork.");
const stream = await navigator.mediaDevices.getUserMedia({
audio: { echoCancellation: true, noiseSuppression: true, autoGainControl: true },
});
voiceRealtime.stream = stream;
setMicDiagnostics(stream);
for (const track of stream.getAudioTracks()) {
track.addEventListener("mute", () => setMicDiagnostics(stream));
track.addEventListener("unmute", () => setMicDiagnostics(stream));
track.addEventListener("ended", () => setMicDiagnostics(stream));
peer.addTrack(track, stream);
}
} else {
setVoiceRuntimeSnapshot((current) => ({ ...current, micDiagnostics: "Voice command is using typed or injected audio, not the microphone." }));
peer.addTransceiver("audio", { direction: "recvonly" });
}
const audio = document.createElement("audio");
audio.autoplay = true;View on GitHub (pinned to 2b7df46e8a)
Solutions
- Grant OpenWork microphone access in System Settings > Privacy & Security > Microphone, then restart the app
- Re-trigger the permission prompt (requestMacMicrophoneAccess) and accept it
- Verify the packaged app has NSSMicrophoneUsageDescription and the mic entitlement — rebuild/re-sign if missing
- Fall back to audioInput = false (typed voice commands) until permission is granted
Example fix
// before
await connectRealtime(true);
// after
try {
await connectRealtime(true);
} catch (e) {
if (String(e).includes("macOS denied microphone access")) {
toast.error("Enable OpenWork in System Settings > Privacy & Security > Microphone, then retry.");
}
} Defensive patterns
Strategy: try-catch
Validate before calling
const granted = await requestMacMicrophoneAccess();
if (!granted) {
showMacMicSetupDialog();
return;
} Try / catch
try {
await connectRealtime(true);
} catch (e) {
if (e instanceof Error && e.message.includes("System Settings > Privacy & Security > Microphone")) {
toast.error("Grant OpenWork microphone access in System Settings, then restart the app.");
} else throw e;
} Prevention
- Trigger the macOS mic permission prompt early (on first launch) rather than mid-connect
- Ship the app with NSSMicrophoneUsageDescription and the mic entitlement
- Provide an in-app link that opens System Settings > Microphone
- Fall back to typed voice commands when permission is denied
When it happens
Trigger: requestMacMicrophoneAccess() resolves false — the OS-level microphone permission for OpenWork is denied or undetermined-and-dismissed — while connecting with audio input on macOS.
Common situations: User previously denied the macOS mic prompt; the packaged app lacks the microphone entitlement / Info.plist NSSMicrophoneUsageDescription so the OS silently denies; enterprise MDM blocking mic access; permission reset via System Settings after an update.
Related errors
- Microphone capture is unavailable in this runtime.
- Failed to write .opencode/openwork.json
- Environment variable store could not be read
- unsupported_resource_permissions
- automation_owner_inactive
AI-assisted analysis of different-ai/openwork@2b7df46e8a (2026-09-01).
Data as JSON: /api/errors/a3163cc2953f3825.
Report an issue: GitHub.