jamiepine/voicebox · error · ValueError

Preset profile {profile.id} only supports engine '{preset_en

Error message

Preset profile {profile.id} only supports engine '{preset_engine}', not '{engine}'

What it means

Raised by validate_profile_engine when a preset profile's preset_engine does not match the engine argument passed to the call (profiles.py:122-125). Preset profiles are pinned to one engine — the engine chosen when the preset was bound — so a generate/speak call that requests a different engine is rejected rather than silently producing output on the wrong engine.

Source

Thrown at backend/services/profiles.py:123

    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,
    db: Session,
) -> VoiceProfileResponse:

View on GitHub (pinned to 51f49dea19)

Solutions

  1. Read profile.preset_engine and pass that exact value as the engine argument.
  2. If the UI exposes an engine selector, disable it (or auto-set it) when a preset profile is selected.
  3. If the engine names changed across versions, migrate preset_engine values to the new names.
  4. If you genuinely need a different engine, clone the voice into a non-preset profile first.

Example fix

# before
await generate(profile, engine='chatterbox')  # profile.preset_engine='qwen'
# after
await generate(profile, engine=profile.preset_engine)
Defensive patterns

Strategy: validation

Validate before calling

def engine_matches_preset(profile, engine: str) -> bool:
    return getattr(profile, 'preset_engine', None) == engine

# before generate:
if profile.voice_type == 'preset' and not engine_matches_preset(profile, engine):
    raise HTTPException(409, f"This preset profile only supports engine '{profile.preset_engine}'.")

Type guard

def is_compatible_engine(profile, engine: str) -> bool:
    vt = getattr(profile, 'voice_type', None) or 'cloned'
    if vt == 'preset':
        return getattr(profile, 'preset_engine', None) == engine
    return True

Try / catch

try:
    validate_profile_engine(profile, engine)
except ValueError as e:
    if 'only supports engine' in str(e):
        raise HTTPException(409, str(e))
    raise HTTPException(400, str(e))

Prevention

When it happens

Trigger: POST /generate with engine='chatterbox' against a profile whose preset_engine='qwen'; client default engine differs from the engine used to create the preset; a session-level engine override conflicts with the preset's binding.

Common situations: Frontend has a global engine selector that the user changed after selecting a preset voice; API consumer hard-coded an engine string without reading the profile's preset_engine; engine names changed across versions (e.g. 'chatterbox' vs 'chatterbox_turbo').

Related errors


AI-assisted analysis of jamiepine/voicebox@51f49dea19 (2026-08-12). Data as JSON: /api/errors/f11d88ab82a80d28. Report an issue: GitHub.