{"record":{"id":"ba4d2c5b41f8a0d9","repo":"jamiepine/voicebox","slug":"designed-profile-profile-id-is-missing-design-pr-ba4d2c","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":564,"sourceCode":"\n    # ── Preset profiles: return engine-specific voice reference ──\n    if voice_type == \"preset\":\n        if not profile.preset_engine or not profile.preset_voice_id:\n            raise ValueError(f\"Preset profile {profile_id} is missing preset engine metadata\")\n        if profile.preset_engine != engine:\n            raise ValueError(\n                f\"Preset profile {profile_id} only supports engine '{profile.preset_engine}', not '{engine}'\"\n            )\n        return {\n            \"voice_type\": \"preset\",\n            \"preset_engine\": profile.preset_engine,\n            \"preset_voice_id\": profile.preset_voice_id,\n        }\n\n    # ── Designed profiles: return text description (future) ──\n    if voice_type == \"designed\":\n        if not profile.design_prompt or not profile.design_prompt.strip():\n            raise ValueError(f\"Designed profile {profile_id} is missing design_prompt\")\n        return {\n            \"voice_type\": \"designed\",\n            \"design_prompt\": profile.design_prompt,\n        }\n\n    if engine not in CLONING_ENGINES:\n        raise ValueError(f\"Engine '{engine}' does not support cloned voice profiles\")\n\n    # ── Cloned profiles: create from audio samples ──\n    samples = db.query(DBProfileSample).filter_by(profile_id=profile_id).all()\n\n    if not samples:\n        raise ValueError(f\"No samples found for profile {profile_id}\")\n\n    tts_model = get_tts_backend_for_engine(engine)\n\n    if len(samples) == 1:\n        sample = samples[0]","sourceCodeStart":546,"sourceCodeEnd":582,"githubUrl":"https://github.com/jamiepine/voicebox/blob/51f49dea198384b4eb6087b72c17057c6eb1c1cd/backend/services/profiles.py#L546-L582","documentation":"Raised in the designed branch of create_voice_prompt_from_profile() when a profile whose voice_type == 'designed' has no design_prompt or an empty/whitespace-only design_prompt. Designed profiles synthesize from a text description, so the prompt is the essential payload; without it the backend has nothing to send to the design model.","triggerScenarios":"A designed profile row was created with design_prompt=NULL or empty string; the field was cleared by an update; voice_type was flipped to 'designed' without supplying a prompt.","commonSituations":"Profile creation API accepted voice_type='designed' before validation tightened; migration altered voice_type values without backfilling design_prompt; test fixtures omitting the field.","solutions":["Set a non-empty design_prompt on the profile row: UPDATE voice_profiles SET design_prompt='...' WHERE id=....","Recreate the designed profile through create_profile with a valid design_prompt payload.","Add an app-layer validator that rejects voice_type='designed' with an empty design_prompt at creation/update time.","If no prompt is intended, switch voice_type to 'preset' or 'cloned'."],"exampleFix":"// before: designed profile with design_prompt=NULL\n// after\nprofile.design_prompt = 'warm female voice, mid-pitch, calm pace'\ndb.commit()","handlingStrategy":"validation","validationCode":"profile = db.query(DBVoiceProfile).filter_by(id=profile_id).first()\nif (profile.voice_type or 'cloned') == 'designed' and not (profile.design_prompt or '').strip():\n    raise HTTPException(409, 'Designed profile is missing design_prompt')","typeGuard":null,"tryCatchPattern":"try:\n    prompt = await create_voice_prompt_from_profile(profile_id, db, engine=engine)\nexcept ValueError as e:\n    if 'missing design_prompt' in str(e):\n        raise HTTPException(409, str(e))\n    raise","preventionTips":["Validate design_prompt is non-empty at profile create/update time when voice_type='designed'.","Add a NOT NULL + CHECK constraint for design_prompt when voice_type='designed'.","Test the designed-profile creation path with empty/whitespace prompts."],"tags":["profiles","data-integrity","designed","voicebox"],"backgroundTag":null,"analyzedSha":"51f49dea198384b4eb6087b72c17057c6eb1c1cd","analyzedAt":"2026-08-12T16:51:42.824Z","schemaVersion":2},"datasetVersion":"2026-08-12T18:17:37.767Z"}