Aider-AI/aider · warning · ValueError

Device '{device_name}' not found. Available input devices: {

Error message

Device '{device_name}' not found. Available input devices: {available_inputs}

What it means

Voice.__init__ in aider/voice.py enumerates sounddevice devices via sd.query_devices() and, when a device_name was supplied, does substring matching against each device's name. If no device name contains the requested substring, it raises ValueError listing all devices with max_input_channels > 0. Two caveats from the source: matching is case-sensitive substring containment, and the whole block is wrapped in except (OSError, ModuleNotFoundError) -> SoundDeviceError, so backend failures masquerade as a different error.

Source

Thrown at aider/voice.py:60

            raise SoundDeviceError
        try:
            print("Initializing sound device...")
            import sounddevice as sd

            self.sd = sd

            devices = sd.query_devices()

            if device_name:
                # Find the device with matching name
                device_id = None
                for i, device in enumerate(devices):
                    if device_name in device["name"]:
                        device_id = i
                        break
                if device_id is None:
                    available_inputs = [d["name"] for d in devices if d["max_input_channels"] > 0]
                    raise ValueError(
                        f"Device '{device_name}' not found. Available input devices:"
                        f" {available_inputs}"
                    )

                print(f"Using input device: {device_name} (ID: {device_id})")

                self.device_id = device_id
            else:
                self.device_id = None

        except (OSError, ModuleNotFoundError):
            raise SoundDeviceError
        if audio_format not in ["wav", "mp3", "webm"]:
            raise ValueError(f"Unsupported audio format: {audio_format}")
        self.audio_format = audio_format

    def callback(self, indata, frames, time, status):
        """This is called (from a separate thread) for each audio block."""

View on GitHub (pinned to 5dc9490bb3)

Solutions

  1. Copy an exact substring from the 'Available input devices' list in the error message, keeping the casing.
  2. Verify the device is connected and enabled at OS level (unplug/replug, check system sound settings) and retry.
  3. Omit device_name entirely (self.device_id = None) to use the system default input.
  4. List devices first to pick the name programmatically: python -c "import sounddevice as sd; [print(i, d['name']) for i, d in enumerate(sd.query_devices())]".

Example fix

# before
voice = Voice(device_name="Yeti")   # ValueError if actual name is 'Blue Yeti 2'

# after
import sounddevice as sd
names = [d["name"] for d in sd.query_devices() if d["max_input_channels"] > 0]
pick = next((n for n in names if "yeti" in n.lower()), None)
voice = Voice(device_name=pick)  # None -> system default
Defensive patterns

Strategy: validation

Validate before calling

import sounddevice as sd

def resolve_device(name=None):
    try:
        devices = sd.query_devices()
    except (OSError, ModuleNotFoundError):
        return None  # no audio backend at all
    inputs = [d["name"] for d in devices if d["max_input_channels"] > 0]
    if name:
        for n in inputs:
            if name in n:  # same substring rule as Voice.__init__
                return n
    return inputs[0] if inputs else None  # fall back to default

Try / catch

try:
    voice = Voice(device_name=name)
except ValueError as e:
    if "not found. Available input devices" in str(e):
        voice = Voice()  # retry with system default
    else:
        raise

Prevention

When it happens

Trigger: Constructing Voice(device_name="...") where the substring appears in no installed device name — typo, wrong casing ('MacBook' vs 'MacBook Pro' casing differences), device unplugged/disabled, or name from a different machine. Available input device names are printed in the error, so you can diff requested vs actual.

Common situations: Hardcoding an input device name from one machine onto another (headset disconnected, USB mic moved); Linux where PulseAudio/PipeWire device names differ from the GUI labels; casing mismatches since 'in device["name"]' is exact-case substring matching.

Related errors


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