jamiepine/voicebox · error · ValueError
Preset profiles require both preset_engine and preset_voice_
Error message
Preset profiles require both preset_engine and preset_voice_id
What it means
Returned by _validate_profile_fields when voice_type=='preset' but preset_engine or preset_voice_id is falsy. A preset profile is an engine-native voice (kokoro/qwen_custom_voice), so both identifiers are mandatory; one without the other is meaningless. Fires during create_profile before any DB write.
Source
Thrown at backend/services/profiles.py:173
existing_profile = db.query(DBVoiceProfile).filter_by(name=data.name).first()
if existing_profile:
raise ValueError(f"A profile with the name '{data.name}' already exists. Please choose a different name.")
# Auto-set default_engine for preset profiles
default_engine = data.default_engine
voice_type = data.voice_type or "cloned"
if voice_type == "preset" and data.preset_engine and not default_engine:
default_engine = data.preset_engine
validation_error = _validate_profile_fields(
voice_type=voice_type,
preset_engine=data.preset_engine,
preset_voice_id=data.preset_voice_id,
design_prompt=data.design_prompt,
default_engine=default_engine,
)
if validation_error:
raise ValueError(validation_error)
db_profile = DBVoiceProfile(
id=str(uuid.uuid4()),
name=data.name,
description=data.description,
language=data.language,
voice_type=voice_type,
preset_engine=data.preset_engine,
preset_voice_id=data.preset_voice_id,
design_prompt=data.design_prompt,
default_engine=default_engine,
personality=data.personality,
created_at=datetime.utcnow(),
updated_at=datetime.utcnow(),
)
db.add(db_profile)
db.commit()View on GitHub (pinned to 51f49dea19)
Solutions
- Send both preset_engine and preset_voice_id together, e.g. {voice_type:'preset', preset_engine:'kokoro', preset_voice_id:'af_heart'}.
- If you do not have a specific preset voice, use voice_type:'cloned' (default) instead.
- Validate the pair in the client before submit and disable the create button until both are set.
Example fix
// before
{"name":"Announcer","voice_type":"preset","preset_engine":"kokoro"}
// after
{"name":"Announcer","voice_type":"preset","preset_engine":"kokoro","preset_voice_id":"af_heart"} Defensive patterns
Strategy: validation
Validate before calling
def is_valid_preset_payload(data) -> bool:
return (
data.voice_type == "preset"
and bool(data.preset_engine)
and bool(data.preset_voice_id)
)
if data.voice_type == "preset" and not is_valid_preset_payload(data):
raise HTTPException(400, "preset profiles need both preset_engine and preset_voice_id") Type guard
def is_complete_preset(data) -> bool:
return (
getattr(data, "voice_type", None) == "preset"
and bool(getattr(data, "preset_engine", None))
and bool(getattr(data, "preset_voice_id", None))
) Prevention
- In the UI, only enable 'create' for preset profiles once both engine and voice are chosen.
- Keep preset_engine and preset_voice_id in a single composite selection so one cannot be sent without the other.
- Run the same _validate_profile_fields check client-side before submit.
When it happens
Trigger: POSTing {voice_type:'preset'} with preset_engine omitted, preset_voice_id omitted, or either set to empty string. Note create_profile only auto-fills default_engine from preset_engine; it never fills in a missing voice_id.
Common situations: Frontend exposes a voice picker but the engine/voice selection is sent as two separate fields and one is left blank; client defaulting voice_type to 'preset' while only sending preset_engine.
Related errors
- Preset profiles must use their preset_engine as default_engi
- Preset voice '{preset_voice_id}' is not valid for engine '{p
- Designed profiles require a design_prompt
- A profile with the name '{data.name}' already exists. Please
- Designed profiles cannot set preset_engine or preset_voice_i
AI-assisted analysis of jamiepine/voicebox@51f49dea19 (2026-08-12).
Data as JSON: /api/errors/dc80c09759435b48.
Report an issue: GitHub.