{"record":{"id":"9289dec50cde6433","repo":"jamiepine/voicebox","slug":"designed-profile-profile-id-is-missing-design-pr","errorCode":null,"errorMessage":"Designed profile {profile.id} is missing design_prompt","messagePattern":"Designed profile (.+?) is missing design_prompt","errorType":"exception","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"backend/services/profiles.py","lineNumber":131,"sourceCode":"\ndef validate_profile_engine(profile, engine: str) -> None:\n    voice_type = getattr(profile, \"voice_type\", None) or \"cloned\"\n\n    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:","sourceCodeStart":113,"sourceCodeEnd":149,"githubUrl":"https://github.com/jamiepine/voicebox/blob/51f49dea198384b4eb6087b72c17057c6eb1c1cd/backend/services/profiles.py#L113-L149","documentation":"Raised by validate_profile_engine when profile.voice_type == 'designed' but design_prompt is missing or whitespace-only (profiles.py:128-131). A designed voice is synthesized from its design_prompt; without one the profile is malformed and the engine cannot produce the intended voice. Like error 256, this is a data-integrity failure on the row.","triggerScenarios":"A profile row was set to voice_type='designed' without a design_prompt (manual SQL, migration that reclassified rows, create_profile bug that allowed the combination); the design_prompt was cleared via an edit.","commonSituations":"Schema migration reclassified cloned rows as 'designed' without backfilling design_prompt; admin edited the row; a fork changed the create-time validation.","solutions":["Backfill design_prompt: UPDATE voice_profiles SET design_prompt='<text>' WHERE id='<id>';.","If the row is not actually designed, set voice_type to 'cloned' or 'preset' as appropriate.","Ensure create_profile requires design_prompt when voice_type='designed'.","Add a DB CHECK constraint to enforce the combination."],"exampleFix":"-- before\nSELECT voice_type, design_prompt FROM voice_profiles WHERE id='<id>';\n-- voice_type=designed, design_prompt=NULL\n-- after\nUPDATE voice_profiles SET design_prompt='warm narrator, slight rasp' WHERE id='<id>';","handlingStrategy":"type-guard","validationCode":"def designed_profile_complete(profile) -> bool:\n    dp = getattr(profile, 'design_prompt', None)\n    return (\n        getattr(profile, 'voice_type', None) == 'designed'\n        and isinstance(dp, str) and bool(dp.strip())\n    )","typeGuard":"def is_complete_designed(profile) -> bool:\n    dp = getattr(profile, 'design_prompt', None)\n    return (\n        getattr(profile, 'voice_type', None) == 'designed'\n        and isinstance(dp, str) and bool(dp.strip())\n    )","tryCatchPattern":"try:\n    validate_profile_engine(profile, engine)\nexcept ValueError as e:\n    if 'missing design_prompt' in str(e):\n        raise HTTPException(409, str(e))  # data integrity\n    raise HTTPException(400, str(e))","preventionTips":["Require design_prompt at create time when voice_type='designed'.","Add a DB CHECK constraint enforcing design_prompt when voice_type='designed'.","Audit designed rows after any migration that reclassified voice_type."],"tags":["profile","designed","validation","data-integrity"],"backgroundTag":null,"analyzedSha":"51f49dea198384b4eb6087b72c17057c6eb1c1cd","analyzedAt":"2026-08-12T16:51:42.824Z","schemaVersion":2},"datasetVersion":"2026-08-12T18:17:37.767Z"}