jamiepine/voicebox · error · ValueError

Preset profiles must use their preset_engine as default_engi

Error message

Preset profiles must use their preset_engine as default_engine

What it means

Returned by _validate_profile_fields when voice_type=='preset', a default_engine was supplied, and default_engine != preset_engine. A preset profile's synthesis engine is fixed by its preset, so default_engine must either equal preset_engine or be omitted (create_profile auto-fills it from preset_engine).

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

  1. Drop default_engine from the request and let create_profile auto-fill it from preset_engine.
  2. Or set default_engine equal to preset_engine explicitly.
  3. Audit the client form: default_engine should be read-only/hidden when voice_type is 'preset'.

Example fix

// before
{"voice_type":"preset","preset_engine":"kokoro","preset_voice_id":"af_heart","default_engine":"qwen"}
// after - omit default_engine
{"voice_type":"preset","preset_engine":"kokoro","preset_voice_id":"af_heart"}
Defensive patterns

Strategy: validation

Validate before calling

def normalize_preset_default_engine(data):
    # for preset profiles, default_engine must equal preset_engine or be None
    if data.voice_type == "preset" and data.default_engine and data.default_engine != data.preset_engine:
        data.default_engine = None  # let the service auto-fill from preset_engine
    return data

Type guard

def preset_engine_consistent(data) -> bool:
    if data.voice_type != "preset":
        return True
    de = getattr(data, "default_engine", None)
    return de is None or de == data.preset_engine

Prevention

When it happens

Trigger: POSTing a preset profile with default_engine set to a different engine than preset_engine, e.g. preset_engine:'kokoro' and default_engine:'qwen'.

Common situations: Copy-pasting a cloned-profile template that carries default_engine:'qwen' and switching voice_type to 'preset' without clearing default_engine; UI pre-populating default_engine from a global setting.

Related errors


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