Aider-AI/aider · error · SoundDeviceError

Error accessing audio input device: {err}

Error message

Error accessing audio input device: {err}

What it means

The second audio failure point in raw_record_and_transcribe: after the sample-rate query succeeds, opening sd.InputStream for the selected device raised sounddevice.PortAudioError, re-raised as SoundDeviceError with the underlying PortAudio message appended ('Error accessing audio input device: {err}'). Unlike error 51, the device enumerated but the stream could not be opened — typically the device is busy, has zero input channels despite listing, or sample-rate mismatch.

Source

Thrown at aider/voice.py:138

        try:
            sample_rate = int(self.sd.query_devices(self.device_id, "input")["default_samplerate"])
        except (TypeError, ValueError):
            sample_rate = 16000  # fallback to 16kHz if unable to query device
        except self.sd.PortAudioError:
            raise SoundDeviceError(
                "No audio input device detected. Please check your audio settings and try again."
            )

        self.start_time = time.time()

        try:
            with self.sd.InputStream(
                samplerate=sample_rate, channels=1, callback=self.callback, device=self.device_id
            ):
                prompt(self.get_prompt, refresh_interval=0.1)
        except self.sd.PortAudioError as err:
            raise SoundDeviceError(f"Error accessing audio input device: {err}")

        with sf.SoundFile(temp_wav, mode="x", samplerate=sample_rate, channels=1) as file:
            while not self.q.empty():
                file.write(self.q.get())

        use_audio_format = self.audio_format

        # Check file size and offer to convert to mp3 if too large
        file_size = os.path.getsize(temp_wav)
        if file_size > 24.9 * 1024 * 1024 and self.audio_format == "wav":
            print("\nWarning: {temp_wav} is too large, switching to mp3 format.")
            use_audio_format = "mp3"

        filename = temp_wav
        if use_audio_format != "wav":
            try:
                new_filename = tempfile.mktemp(suffix=f".{use_audio_format}")
                audio = AudioSegment.from_wav(temp_wav)

View on GitHub (pinned to 5dc9490bb3)

Solutions

  1. Read the appended PortAudio text — 'Device unavailable' means busy (close other apps using the mic), 'Invalid sample rate' means rate mismatch.
  2. Close other applications capturing the mic (browser tabs, conferencing apps) and retry.
  3. Grant microphone permission to your terminal/IDE (macOS System Settings > Privacy & Security > Microphone).
  4. Reconnect/reselect the USB device or pass an explicit working device_name to Voice().
Defensive patterns

Strategy: try-catch

Validate before calling

import sounddevice as sd

def can_open_input(device=None) -> bool:
    try:
        with sd.InputStream(device=device, channels=1, samplerate=16000):
            return True
    except Exception:
        return False

Try / catch

from aider.voice import SoundDeviceError, Voice
try:
    text = Voice(device_name=dev).record_and_transcribe()
except SoundDeviceError as e:
    if "Error accessing audio input device" in str(e):
        # underlying PortAudio text is appended: busy vs rate vs permission
        print(f"Mic unavailable: {e}")
        text = input("Type instead: ")
    else:
        raise

Prevention

When it happens

Trigger: Opening the input stream with device=self.device_id when another app holds the mic exclusively (Zoom/Meet/browser), the queried default_samplerate is unsupported by the device, or the device disappeared between enumeration and stream open (USB unplugged).

Common situations: Conference call holding the microphone when aider voice is invoked; USB mic unplugged mid-flow; devices whose advertised default_samplerate is rejected by PortAudio on open; macOS mic permission not granted to the terminal app.

Related errors


AI-assisted analysis of Aider-AI/aider@5dc9490bb3 (2026-08-15). Data as JSON: /api/errors/6dbb41eced3628a7. Report an issue: GitHub.