jamiepine/voicebox · warning · HTTPException

{exception message from create_channel (ValueError)}

Error message

{exception message from create_channel (ValueError)}

What it means

Returned as a 400 from POST /channels wrapping any ValueError raised by channels.create_channel. The service uses ValueError for expected validation failures (duplicate channel name, invalid device/source config, out-of-range parameters) so they surface as client errors rather than 500s. The detail is str(e) — the service's specific message.

Source

Thrown at backend/routes/channels.py:28

router = APIRouter()


@router.get("/channels", response_model=list[models.AudioChannelResponse])
async def list_channels(db: Session = Depends(get_db)):
    """List all audio channels."""
    return await channels.list_channels(db)


@router.post("/channels", response_model=models.AudioChannelResponse)
async def create_channel(
    data: models.AudioChannelCreate,
    db: Session = Depends(get_db),
):
    """Create a new audio channel."""
    try:
        return await channels.create_channel(data, db)
    except ValueError as e:
        raise HTTPException(status_code=400, detail=str(e))


@router.get("/channels/{channel_id}", response_model=models.AudioChannelResponse)
async def get_channel(
    channel_id: str,
    db: Session = Depends(get_db),
):
    """Get an audio channel by ID."""
    channel = await channels.get_channel(channel_id, db)
    if not channel:
        raise HTTPException(status_code=404, detail="Channel not found")
    return channel


@router.put("/channels/{channel_id}", response_model=models.AudioChannelResponse)
async def update_channel(
    channel_id: str,
    data: models.AudioChannelUpdate,

View on GitHub (pinned to 51f49dea19)

Solutions

  1. Read the detail string — it names the exact business-rule violation.
  2. For duplicate-name errors, choose a unique name or first delete/rename the conflicting channel.
  3. For device errors, list available audio devices and use a valid id.
  4. Move repeated business rules into the Pydantic model validators so they fail at parse time with structured errors.
Defensive patterns

Strategy: try-catch

Validate before calling

// Pre-check business rules the service enforces.
const existing = await listChannels();
if (existing.some(c => c.name === data.name)) {
  throw new Error('Channel name already exists');
}

Type guard

function isUniqueChannelName(name: string, existing: { name: string }[]): boolean {
  return !existing.some(c => c.name === name);
}

Try / catch

try {
  const r = await fetch('/channels', { method: 'POST', body: JSON.stringify(data) });
  if (r.status === 400) {
    const { detail } = await r.json();
    showUserFacingError(detail); // names the business-rule violation
    return;
  }
} catch (e) { showNetworkError(e); }

Prevention

When it happens

Trigger: POST /channels with a body that passes Pydantic validation but fails business-rule validation inside create_channel — e.g. a channel name that already exists, an audio device id that is not present on the system, an invalid source binding, or a parameter outside an allowed range.

Common situations: Creating a channel with a duplicate name; referencing an audio input device that was disconnected; a source value that conflicts with an existing channel; feeding a config that the service's deeper checks reject.

Related errors


AI-assisted analysis of jamiepine/voicebox@51f49dea19 (2026-08-12). Data as JSON: /api/errors/f9dc9cf2381073ce. Report an issue: GitHub.