{"record":{"id":"4488bfd3ccfec640","repo":"lfnovo/open-notebook","slug":"failed-to-fetch-episode-profile","errorCode":null,"errorMessage":"Failed to fetch episode profile","messagePattern":"Failed to fetch episode profile","errorType":"http","errorClass":"HTTPException","httpStatus":500,"severity":"error","filePath":"api/routers/episode_profiles.py","lineNumber":119,"sourceCode":"    try:\n        profile = await EpisodeProfile.get_by_name(profile_name)\n\n        if not profile:\n            raise HTTPException(\n                status_code=404, detail=f\"Episode profile '{profile_name}' not found\"\n            )\n\n        return _profile_to_response(\n            profile, await _speaker_name_for(profile.speaker_config)\n        )\n\n    except HTTPException:\n        raise\n    except OpenNotebookError:\n        raise\n    except Exception as e:\n        logger.error(f\"Failed to fetch episode profile '{profile_name}': {e}\")\n        raise HTTPException(\n            status_code=500, detail=\"Failed to fetch episode profile\"\n        )\n\n\nclass EpisodeProfileCreate(BaseModel):\n    name: str = Field(..., description=\"Unique profile name\")\n    description: str = Field(\"\", description=\"Profile description\")\n    speaker_config: str = Field(\n        ...,\n        description=(\n            \"speaker_profile record ID (a profile name is also accepted \"\n            \"for backward compatibility)\"\n        ),\n    )\n    outline_llm: Optional[str] = Field(None, description=\"Model record ID for outline\")\n    transcript_llm: Optional[str] = Field(\n        None, description=\"Model record ID for transcript\"\n    )","sourceCodeStart":101,"sourceCodeEnd":137,"githubUrl":"https://github.com/lfnovo/open-notebook/blob/a7de90d38aaf18ee85fd661854d35c11e44613e2/api/routers/episode_profiles.py#L101-L137","documentation":"Generic 500 raised when fetching a single episode profile fails unexpectedly (outside HTTPException/OpenNotebookError). The underlying exception is logged with the profile name.","triggerScenarios":"DB connectivity failure during EpisodeProfile.get_by_name, or an exception while building the response (e.g., resolving the speaker name for profile.speaker_config fails).","commonSituations":"SurrealDB down or restarting; the profile references a dangling speaker_config that blows up during _speaker_name_for; schema changes after partial migration.","solutions":["Check the API log line 'Failed to fetch episode profile <name>' for the traceback","Verify the profile's speaker_config references an existing SpeakerProfile","Confirm DB health and retry","Repair or clear dangling references on the profile record"],"exampleFix":null,"handlingStrategy":"retry","validationCode":null,"typeGuard":null,"tryCatchPattern":"try:\n    return await client.get(f\"/api/episode-profiles/{quote(name)}\")\nexcept httpx.HTTPStatusError as e:\n    if e.response.status_code >= 500:\n        await asyncio.sleep(1)\n        return await client.get(f\"/api/episode-profiles/{quote(name)}\")\n    raise","preventionTips":["Keep episode profiles' speaker_config pointing at live SpeakerProfile records","Check server logs for the traceback before guessing","Use dependency health checks before reads"],"tags":["http-500","internal-error","episode-profile","database"],"backgroundTag":"internal-server-error","analyzedSha":"a7de90d38aaf18ee85fd661854d35c11e44613e2","analyzedAt":"2026-08-27T02:39:58.166Z","schemaVersion":2},"datasetVersion":"2026-08-27T03:17:27.898Z"}