{"record":{"id":"2d22606247b6195d","repo":"jamiepine/voicebox","slug":"profile-not-found","errorCode":null,"errorMessage":"Profile not found","messagePattern":"Profile not found","errorType":"http","errorClass":"HTTPException","httpStatus":404,"severity":"error","filePath":"backend/routes/generations.py","lineNumber":67,"sourceCode":"    return row\n\n\ndef _resolve_generation_engine(data: models.GenerationRequest, profile) -> str:\n    return data.engine or getattr(profile, \"default_engine\", None) or getattr(profile, \"preset_engine\", None) or \"qwen\"\n\n\n@router.post(\"/generate\", response_model=models.GenerationResponse)\nasync def generate_speech(\n    data: models.GenerationRequest,\n    db: Session = Depends(get_db),\n):\n    \"\"\"Generate speech from text using a voice profile.\"\"\"\n    task_manager = get_task_manager()\n    generation_id = str(uuid.uuid4())\n\n    profile = await profiles.get_profile(data.profile_id, db)\n    if not profile:\n        raise HTTPException(status_code=404, detail=\"Profile not found\")\n\n    from ..backends import engine_has_model_sizes\n\n    engine = _resolve_generation_engine(data, profile)\n    try:\n        profiles.validate_profile_engine(profile, engine)\n    except ValueError as e:\n        raise HTTPException(status_code=400, detail=str(e))\n\n    model_size = (data.model_size or \"1.7B\") if engine_has_model_sizes(engine) else None\n\n    text = data.text\n    source = \"manual\"\n    if data.personality and getattr(profile, \"personality\", None):\n        try:\n            llm_result = await personality.rewrite_as_profile(profile.personality, data.text)\n        except ValueError as e:\n            raise HTTPException(status_code=400, detail=str(e))","sourceCodeStart":49,"sourceCodeEnd":85,"githubUrl":"https://github.com/jamiepine/voicebox/blob/51f49dea198384b4eb6087b72c17057c6eb1c1cd/backend/routes/generations.py#L49-L85","documentation":"Returned as HTTP 404 by POST /generate. The route awaits profiles.get_profile(data.profile_id) and raises this 404 when it returns None. Generation requires a voice profile (cloned, preset, designed, or import) to exist; without one, no TTS target is available.","triggerScenarios":"POST /generate with a profile_id that does not exist in the VoiceProfile table; profile was deleted between UI load and submit; profile_id is empty or malformed; using a generation id or version id in the profile_id field.","commonSituations":"Stale profile dropdown after the profile was removed; fresh install with no profiles created yet; misconfigured client defaulting to a placeholder id; cross-environment id from a different DB.","solutions":["Ensure at least one profile exists via GET /profiles before allowing generation.","Source profile_id from a fresh profiles listing, not a cached value.","On 404, refresh the profiles list and prompt the user to pick or create a profile.","Validate the id format (UUID) client-side and confirm it matches a known profile."],"exampleFix":"// before\nawait api.post('/generate', { profile_id: lastProfileId, text });\n// after\nconst profiles = await api.get('/profiles');\nif (!profiles.items.length) { redirect('/profiles/new'); return; }\nawait api.post('/generate', { profile_id: profiles.items[0].id, text });","handlingStrategy":"validation","validationCode":"profile = await profiles.get_profile(data.profile_id, db)\nif profile is None:\n    raise ProfileMissing(data.profile_id)  # would 404\n# safe to POST /generate","typeGuard":"def profile_exists(profile) -> bool:\n    return profile is not None","tryCatchPattern":"try:\n    client.post('/generate', json=payload)\nexcept HTTPStatusError as e:\n    if e.response.status_code == 404 and 'Profile' in e.response.json()['detail']:\n        profiles = client.get('/profiles').json()\n        if not profiles['items']:\n            redirect('/profiles/new')\n        else:\n            payload['profile_id'] = profiles['items'][0]['id']\n            client.post('/generate', json=payload)\n        return\n    raise","preventionTips":["Ensure at least one profile exists before enabling generation.","Source profile_id from a fresh /profiles listing.","On 404, refresh profiles and prompt the user to pick or create one.","Validate the id format (UUID) client-side."],"tags":["fastapi","http-404","generate","profiles","tts","not-found","rest"],"backgroundTag":null,"analyzedSha":"51f49dea198384b4eb6087b72c17057c6eb1c1cd","analyzedAt":"2026-08-12T16:51:42.824Z","schemaVersion":2},"datasetVersion":"2026-08-12T18:17:37.767Z"}