jamiepine/voicebox · warning · HTTPException
Sample not found
Error message
Sample not found
What it means
DELETE /profiles/samples/{sample_id} calls profiles.delete_profile_sample; if it returns falsy the route raises 404 'Sample not found'. The id did not match a sample row, or the row was already deleted. Note this route is keyed on sample_id alone (no profile_id in the path), so the 4040 cannot tell you whether the parent profile exists.
Source
Thrown at backend/routes/profiles.py:211
@router.get("/profiles/{profile_id}/samples", response_model=list[models.ProfileSampleResponse])
async def get_profile_samples(
profile_id: str,
db: Session = Depends(get_db),
):
"""Get all samples for a profile."""
return await profiles.get_profile_samples(profile_id, db)
@router.delete("/profiles/samples/{sample_id}")
async def delete_profile_sample(
sample_id: str,
db: Session = Depends(get_db),
):
"""Delete a profile sample."""
success = await profiles.delete_profile_sample(sample_id, db)
if not success:
raise HTTPException(status_code=404, detail="Sample not found")
return {"message": "Sample deleted successfully"}
@router.put("/profiles/samples/{sample_id}", response_model=models.ProfileSampleResponse)
async def update_profile_sample(
sample_id: str,
data: models.ProfileSampleUpdate,
db: Session = Depends(get_db),
):
"""Update a profile sample's reference text."""
sample = await profiles.update_profile_sample(sample_id, data.reference_text, db)
if not sample:
raise HTTPException(status_code=404, detail="Sample not found")
return sample
@router.post("/profiles/{profile_id}/avatar", response_model=models.VoiceProfileResponse)
async def upload_profile_avatar(View on GitHub (pinned to 51f49dea19)
Solutions
- Treat the 404 as success for idempotent delete workflows.
- Refresh the sample list via GET /profiles/{profile_id}/samples to confirm whether the id still exists.
- Disable the delete control client-side after the first click to prevent double-submit.
Defensive patterns
Strategy: try-catch
Try / catch
resp = await client.delete(f"/profiles/samples/{sample_id}")
if resp.status_code == 404:
# Already gone -- acceptable for idempotent delete
pass
else:
resp.raise_for_status()
remove_from_ui(sample_id) Prevention
- Treat sample-delete 404 as success.
- Refresh the sample list after deletion to keep client state consistent.
- Disable the delete button after first click.
When it happens
Trigger: DELETE on a sample_id already removed; a typo in the id; a stale UI list referencing a sample deleted by another session; deleting a sample whose row was cleaned up by a storage-reconciliation job.
Common situations: Double-click delete; client cache out of sync; re-running a deletion script after it already succeeded.
Related errors
- Profile not found or no avatar to delete
- Sample not found
- Generation failed; no audio available
- Capture not found
- Audio file not found
AI-assisted analysis of jamiepine/voicebox@51f49dea19 (2026-08-12).
Data as JSON: /api/errors/04b4df1ddb5a15b7.
Report an issue: GitHub.