jamiepine/voicebox · warning · HTTPException
{str(e)}
Error message
{str(e)} What it means
400 from POST /profiles. profiles.create_profile raises ValueError for expected business-rule failures — most commonly 'A profile with the name ... already exists' (duplicate-name guard) and schema-level validation errors produced while building the profile. The route maps ValueError to HTTPException(400, str(e)), so the human-readable reason is forwarded.
Source
Thrown at backend/routes/profiles.py:34
from ..database import VoiceProfile as DBVoiceProfile, get_db
from ..services import channels, export_import, personality, profiles
from ..services.profiles import _profile_to_response
logger = logging.getLogger(__name__)
router = APIRouter()
@router.post("/profiles", response_model=models.VoiceProfileResponse)
async def create_profile(
data: models.VoiceProfileCreate,
db: Session = Depends(get_db),
):
"""Create a new voice profile."""
try:
return await profiles.create_profile(data, db)
except ValueError as e:
raise HTTPException(status_code=400, detail=str(e))
except Exception as e:
raise HTTPException(status_code=400, detail=str(e))
@router.get("/profiles", response_model=list[models.VoiceProfileResponse])
async def list_profiles(db: Session = Depends(get_db)):
"""List all voice profiles."""
return await profiles.list_profiles(db)
@router.post("/profiles/import", response_model=models.VoiceProfileResponse)
async def import_profile(
file: UploadFile = File(...),
db: Session = Depends(get_db),
):
"""Import a voice profile from a ZIP archive."""
MAX_FILE_SIZE = 100 * 1024 * 1024
View on GitHub (pinned to 51f49dea19)
Solutions
- Read detail — it names the exact violated rule (duplicate name, missing preset metadata, etc.).
- For duplicate names, choose a unique name or PUT /profiles/{id} to update the existing one instead.
- For voice_type='preset', include preset_engine and preset_voice_id; for 'designed', include design_prompt.
- GET /profiles to reconcile client state with the server before retrying.
Example fix
// before
POST /profiles {"name":"Morgan","voice_type":"preset"} // missing preset fields
// after
POST /profiles {"name":"Morgan","voice_type":"preset","preset_engine":"kokoro","preset_voice_id":"af_heart"} Defensive patterns
Strategy: validation
Validate before calling
async function createProfile(input) {
const list = await (await fetch('/profiles')).json();
if (list.some(p => p.name.toLowerCase() === input.name.toLowerCase())) {
throw new Error(`A profile named '${input.name}' already exists`);
}
if (input.voice_type === 'preset' && (!input.preset_engine || !input.preset_voice_id)) {
throw new Error('preset profiles require preset_engine and preset_voice_id');
}
if (input.voice_type === 'designed' && !input.design_prompt) {
throw new Error('designed profiles require design_prompt');
}
return await fetch('/profiles', {method:'POST', body: JSON.stringify(input)});
} Try / catch
try {
await fetch('/profiles', {method:'POST', body: JSON.stringify(input)});
} catch (e) {
if (e.response?.status === 400) {
// detail explains the violated rule (duplicate name, missing preset fields)
showUserError(e.response.detail);
} else throw e;
} Prevention
- Refresh GET /profiles before creating to avoid duplicate-name rejections.
- Send all fields required for the chosen voice_type (preset needs engine+voice_id; designed needs design_prompt).
- Validate language against the schema's allow-list before submit.
When it happens
Trigger: POST /profiles with a name that already exists; language/voice_type/preset fields that fail internal consistency checks (e.g. preset profile missing preset_engine, designed profile missing design_prompt, cloned profile on an engine that doesn't support cloning); reference-text or design_prompt validation failing inside create_profile.
Common situations: User submits the same profile name twice; client didn't refresh the profile list before creating; switching voice_type without supplying the required companion fields (preset_engine + preset_voice_id, or design_prompt); frontend default values violate a server-side rule.
Related errors
- {e}
- A profile with the name '{data.name}' already exists. Please
- Model ${model_size} is not downloaded yet. Use /generate to
- Model {model_size} is not downloaded yet. Use /generate to t
- {display} model is not downloaded yet. Use /generate to trig
AI-assisted analysis of jamiepine/voicebox@51f49dea19 (2026-08-12).
Data as JSON: /api/errors/1e9ec27f4f3b9695.
Report an issue: GitHub.