jamiepine/voicebox · warning · HTTPException
limit must be between 1 and 200
Error message
limit must be between 1 and 200
What it means
Returned as a 400 from GET /captures when the `limit` query param is outside [1, 200]. The route hard-validates limit before calling list_captures because the list endpoint must stay bounded — an unbounded or zero limit would either return nothing or attempt to load the entire table. This is a static guard, independent of service logic.
Source
Thrown at backend/routes/captures.py:77
except Exception as e:
logger.exception("Failed to create capture")
raise HTTPException(status_code=500, detail=str(e))
return models.CaptureCreateResponse(
**capture.model_dump(),
auto_refine=bool(saved.auto_refine),
allow_auto_paste=bool(saved.allow_auto_paste),
)
@router.get("/captures", response_model=models.CaptureListResponse)
async def list_captures_endpoint(
limit: int = 50,
offset: int = 0,
db: Session = Depends(get_db),
):
if limit < 1 or limit > 200:
raise HTTPException(status_code=400, detail="limit must be between 1 and 200")
if offset < 0:
raise HTTPException(status_code=400, detail="offset must be >= 0")
items, total = captures_service.list_captures(db, limit=limit, offset=offset)
return models.CaptureListResponse(items=items, total=total)
@router.get("/captures/{capture_id}", response_model=models.CaptureResponse)
async def get_capture_endpoint(capture_id: str, db: Session = Depends(get_db)):
capture = captures_service.get_capture(capture_id, db)
if not capture:
raise HTTPException(status_code=404, detail="Capture not found")
return capture
@router.get("/captures/{capture_id}/audio")
async def get_capture_audio_endpoint(capture_id: str, db: Session = Depends(get_db)):
"""Stream the original capture audio file."""View on GitHub (pinned to 51f49dea19)
Solutions
- Clamp limit to [1, 200] on the client before building the query string.
- Use the default (omit limit) for normal list views.
- If you genuinely need more than 200, paginate with offset instead of inflating limit.
Example fix
// before
fetch(`/captures?limit=${requested}`) // requested may be 0 or 1000
// after
const limit = Math.min(200, Math.max(1, requested || 50));
fetch(`/captures?limit=${limit}`) Defensive patterns
Strategy: validation
Validate before calling
const limit = Math.min(200, Math.max(1, Number(reqLimit) || 50));
fetch(`/captures?limit=${limit}`); Type guard
function isValidLimit(n: number): boolean {
return Number.isInteger(n) && n >= 1 && n <= 200;
} Prevention
- Clamp limit to [1, 200] on the client.
- For large result sets, paginate with offset instead of raising limit.
- Use a shared pagination helper so all list calls apply the same bounds.
When it happens
Trigger: GET /captures?limit=0, GET /captures?limit=201, or GET /captures?limit=-5 (a negative int parsed by FastAPI). Also limit omitted is fine (default 50).
Common situations: Frontend pagination bug passing limit=0 to mean 'no items'; a UI control allowing values above 200; a script scraping with limit=1000.
Related errors
- offset must be >= 0
- Uploaded file is empty
- {exception message from wrapped ValueError}
- Model ${model_size} is not downloaded yet. Use /generate to
- Model {model_size} is not downloaded yet. Use /generate to t
AI-assisted analysis of jamiepine/voicebox@51f49dea19 (2026-08-12).
Data as JSON: /api/errors/d311f54527713842.
Report an issue: GitHub.