jamiepine/voicebox · error · ValueError
Designed profiles cannot set preset_engine or preset_voice_i
Error message
Designed profiles cannot set preset_engine or preset_voice_id
What it means
Returned by _validate_profile_fields when voice_type=='designed' but preset_engine or preset_voice_id is set. Designed profiles are described purely by design_prompt; preset fields belong to the 'preset' voice_type and are mutually exclusive with 'designed'.
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
- Omit preset_engine and preset_voice_id entirely when voice_type is 'designed'.
- Have the client send only the fields valid for the chosen voice_type.
- Add a client-side rule that clears preset fields when the user selects 'designed'.
Example fix
// before
{"voice_type":"designed","design_prompt":"calm voice","preset_engine":"kokoro"}
// after
{"voice_type":"designed","design_prompt":"calm voice"} Defensive patterns
Strategy: validation
Validate before calling
def designed_is_clean(data) -> bool:
return not (data.preset_engine or data.preset_voice_id)
if data.voice_type == "designed" and not designed_is_clean(data):
raise HTTPException(400, "designed profiles must not include preset_engine/preset_voice_id") Type guard
def is_clean_designed(data) -> bool:
return (
getattr(data, "voice_type", None) == "designed"
and not getattr(data, "preset_engine", None)
and not getattr(data, "preset_voice_id", None)
) Prevention
- Send only the fields relevant to the chosen voice_type.
- Clear preset fields client-side when the user selects 'designed'.
- Build the request body from a per-voice_type schema rather than one shared object.
When it happens
Trigger: POSTing {voice_type:'designed', design_prompt:'...', preset_engine:'kokoro'} or including preset_voice_id on a designed profile.
Common situations: Switching a profile template from 'preset' to 'designed' without clearing the preset fields; client sending the full field set regardless of voice_type.
Related errors
- Designed profiles require a design_prompt
- Cloned profiles cannot set preset_engine or preset_voice_id
- Cloned profiles cannot set design_prompt
- A profile with the name '{data.name}' already exists. Please
- Preset profiles require both preset_engine and preset_voice_
AI-assisted analysis of jamiepine/voicebox@51f49dea19 (2026-08-12).
Data as JSON: /api/errors/2293c861cfe82e3e.
Report an issue: GitHub.