{"record":{"id":"2d6fa3c4c51b329d","repo":"jamiepine/voicebox","slug":"engine-engine-does-not-support-cloned-voice-pr","errorCode":null,"errorMessage":"Engine '{engine}' does not support cloned voice profiles","messagePattern":"Engine '(.+?)' does not support cloned voice profiles","errorType":"exception","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"backend/services/profiles.py","lineNumber":135,"sourceCode":"    if voice_type == \"preset\":\n        preset_engine = getattr(profile, \"preset_engine\", None)\n        preset_voice_id = getattr(profile, \"preset_voice_id\", None)\n        if not preset_engine or not preset_voice_id:\n            raise ValueError(f\"Preset profile {profile.id} is missing preset engine metadata\")\n        if preset_engine != engine:\n            raise ValueError(\n                f\"Preset profile {profile.id} only supports engine '{preset_engine}', not '{engine}'\"\n            )\n        return\n\n    if voice_type == \"designed\":\n        design_prompt = getattr(profile, \"design_prompt\", None)\n        if not design_prompt or not design_prompt.strip():\n            raise ValueError(f\"Designed profile {profile.id} is missing design_prompt\")\n        return\n\n    if engine not in CLONING_ENGINES:\n        raise ValueError(f\"Engine '{engine}' does not support cloned voice profiles\")\n\n\nasync def create_profile(\n    data: VoiceProfileCreate,\n    db: Session,\n) -> VoiceProfileResponse:\n    \"\"\"\n    Create a new voice profile.\n\n    Args:\n        data: Profile creation data\n        db: Database session\n\n    Returns:\n        Created profile\n\n    Raises:\n        ValueError: If a profile with the same name already exists","sourceCodeStart":117,"sourceCodeEnd":153,"githubUrl":"https://github.com/jamiepine/voicebox/blob/51f49dea198384b4eb6087b72c17057c6eb1c1cd/backend/services/profiles.py#L117-L153","documentation":"Raised by validate_profile_engine for the default (cloned) voice_type branch when the requested engine is not in CLONING_ENGINES (profiles.py:134-135). CLONING_ENGINES is {'qwen','luxtts','chatterbox','chatterbox_turbo','tada'} — any other engine string passed against a cloned profile is rejected. This guards against asking a clone-only engine to render a voice it cannot render.","triggerScenarios":"POST /generate with engine='preset' or some non-cloning engine against a cloned profile; typo in the engine name ('chatterbox ' with trailing space, 'Chatterbox' capitalized, 'luxttt' misspelled); an engine string from a newer/older version that is not in this build's CLONING_ENGINES.","commonSituations":"Frontend engine dropdown includes engines that are not cloning-capable; API consumer passed a preset/designed engine name to a cloned profile; engine name casing or spelling mismatch; version skew where one build added an engine the other does not know.","solutions":["Use one of: qwen, luxtts, chatterbox, chatterbox_turbo, tada — match the spelling and casing exactly.","Strip whitespace and lowercase the engine string before passing it.","If you need a preset/designed engine, switch to a profile whose voice_type matches (see errors 256-258).","If you believe the engine should be supported, add it to CLONING_ENGINES in profiles.py after confirming it can clone."],"exampleFix":"# before\nawait generate(cloned_profile, engine='Chatterbox ')\n# after\nawait generate(cloned_profile, engine='chatterbox')\n# or, if you need a preset engine, use a preset profile\nawait generate(preset_profile, engine=preset_profile.preset_engine)","handlingStrategy":"validation","validationCode":"CLONING_ENGINES = {'qwen', 'luxtts', 'chatterbox', 'chatterbox_turbo', 'tada'}\n\ndef engine_supports_clone(engine: str) -> bool:\n    return engine in CLONING_ENGINES\n\n# before generate on a cloned profile:\nif not engine_supports_clone(engine):\n    raise HTTPException(400, f\"Engine '{engine}' cannot render cloned voices. Use one of {sorted(CLONING_ENGINES)}.\")","typeGuard":"def is_cloning_engine(engine: str) -> bool:\n    return isinstance(engine, str) and engine in {'qwen', 'luxtts', 'chatterbox', 'chatterbox_turbo', 'tada'}","tryCatchPattern":"try:\n    validate_profile_engine(profile, engine)\nexcept ValueError as e:\n    if 'does not support cloned voice profiles' in str(e):\n        raise HTTPException(400, str(e) + f\" Valid cloning engines: {sorted(CLONING_ENGINES)}\")\n    raise HTTPException(400, str(e))","preventionTips":["Normalize engine strings to lowercase and strip whitespace before validation.","Filter the UI engine dropdown by the selected profile's voice_type.","Keep CLONING_ENGINES and the UI engine list in sync when adding/removing engines."],"tags":["profile","cloned","engine","validation"],"backgroundTag":null,"analyzedSha":"51f49dea198384b4eb6087b72c17057c6eb1c1cd","analyzedAt":"2026-08-12T16:51:42.824Z","schemaVersion":2},"datasetVersion":"2026-08-12T18:17:37.767Z"}