jamiepine/voicebox · error · ValueError
Preset profile {profile.id} is missing preset engine metadat
Error message
Preset profile {profile.id} is missing preset engine metadata What it means
Raised by validate_profile_engine when profile.voice_type == 'preset' but either preset_engine or preset_voice_id is unset (profiles.py:117-121). A preset profile is identified by these two fields — a preset row missing them is malformed and cannot be used with any engine. This is a data-integrity failure, not a misuse of the API.
Source
Thrown at backend/services/profiles.py:121
return None
if preset_engine or preset_voice_id:
return "Cloned profiles cannot set preset_engine or preset_voice_id"
if design_prompt:
return "Cloned profiles cannot set design_prompt"
if default_engine and default_engine not in CLONING_ENGINES:
return f"Cloned profiles cannot use default engine '{default_engine}'"
return None
def validate_profile_engine(profile, engine: str) -> None:
voice_type = getattr(profile, "voice_type", None) or "cloned"
if voice_type == "preset":
preset_engine = getattr(profile, "preset_engine", None)
preset_voice_id = getattr(profile, "preset_voice_id", None)
if not preset_engine or not preset_voice_id:
raise ValueError(f"Preset profile {profile.id} is missing preset engine metadata")
if preset_engine != engine:
raise ValueError(
f"Preset profile {profile.id} only supports engine '{preset_engine}', not '{engine}'"
)
return
if voice_type == "designed":
design_prompt = getattr(profile, "design_prompt", None)
if not design_prompt or not design_prompt.strip():
raise ValueError(f"Designed profile {profile.id} is missing design_prompt")
return
if engine not in CLONING_ENGINES:
raise ValueError(f"Engine '{engine}' does not support cloned voice profiles")
async def create_profile(
data: VoiceProfileCreate,View on GitHub (pinned to 51f49dea19)
Solutions
- Backfill the missing fields: UPDATE voice_profiles SET preset_engine='<engine>', preset_voice_id='<vid>' WHERE id='<id>';.
- If the row is not actually a preset, set voice_type to 'cloned' or 'designed' as appropriate and clear the preset fields.
- Audit the create_profile path to confirm preset_engine and preset_voice_id are required when voice_type='preset'.
- Add a DB-level CHECK constraint so this cannot recur.
Example fix
-- before: preset row missing metadata SELECT voice_type, preset_engine, preset_voice_id FROM voice_profiles WHERE id='<id>'; -- voice_type=preset, preset_engine=NULL -- after UPDATE voice_profiles SET preset_engine='qwen', preset_voice_id='voice-1' WHERE id='<id>';
Defensive patterns
Strategy: type-guard
Validate before calling
def preset_profile_complete(profile) -> bool:
return (
getattr(profile, 'voice_type', None) == 'preset'
and bool(getattr(profile, 'preset_engine', None))
and bool(getattr(profile, 'preset_voice_id', None))
)
# before validate_profile_engine:
if profile.voice_type == 'preset' and not preset_profile_complete(profile):
raise HTTPException(409, f'Profile {profile.id} is malformed: preset metadata missing.') Type guard
def is_complete_preset(profile) -> bool:
return (
getattr(profile, 'voice_type', None) == 'preset'
and isinstance(getattr(profile, 'preset_engine', None), str) and bool(profile.preset_engine)
and isinstance(getattr(profile, 'preset_voice_id', None), str) and bool(profile.preset_voice_id)
) Try / catch
try:
validate_profile_engine(profile, engine)
except ValueError as e:
if 'missing preset engine metadata' in str(e):
raise HTTPException(409, str(e)) # data integrity, not user error
raise HTTPException(400, str(e)) Prevention
- Enforce preset_engine + preset_voice_id at create time when voice_type='preset'.
- Add a DB CHECK constraint so the combo cannot be partial.
- Audit rows after any migration that touches voice_type.
When it happens
Trigger: A profile row was inserted with voice_type='preset' but preset_engine/preset_voice_id left null (manual SQL, a migration that set voice_type without backfilling the metadata, or a bug in create_profile).
Common situations: Schema migration introduced voice_type and classified some rows as 'preset' without populating the engine fields; an admin edited the row directly; a copy-paste between profiles dropped the fields.
Related errors
- Preset profile {profile.id} only supports engine '{preset_en
- Designed profile {profile.id} is missing design_prompt
- This profile has no personality set. Add one on the profile
- Engine '{engine}' does not support cloned voice profiles
- Preset profiles require both preset_engine and preset_voice_
AI-assisted analysis of jamiepine/voicebox@51f49dea19 (2026-08-12).
Data as JSON: /api/errors/3368c96a4c5f88a4.
Report an issue: GitHub.