lfnovo/open-notebook · error · HTTPException

Failed to update episode profile

Error message

Failed to update episode profile

What it means

Generic 500 raised when updating an episode profile fails unexpectedly — typically during db.save() or while re-resolving speaker_config after the update.

Source

Thrown at api/routers/episode_profiles.py:209

        if "speaker_config" in update_data:
            speaker = await _resolve_speaker_config(update_data["speaker_config"])
            update_data["speaker_config"] = str(speaker.id)
            speaker_name = speaker.name
        for field, value in update_data.items():
            setattr(profile, field, value)

        await profile.save()
        if speaker_name is None:
            speaker_name = await _speaker_name_for(profile.speaker_config)
        return _profile_to_response(profile, speaker_name)

    except HTTPException:
        raise
    except OpenNotebookError:
        raise
    except Exception as e:
        logger.error(f"Failed to update episode profile: {e}")
        raise HTTPException(
            status_code=500, detail="Failed to update episode profile"
        )


@router.delete("/episode-profiles/{profile_id}")
async def delete_episode_profile(profile_id: str):
    """Delete an episode profile"""
    try:
        profile = await EpisodeProfile.get(profile_id)

        if not profile:
            raise HTTPException(
                status_code=404, detail=f"Episode profile '{profile_id}' not found"
            )

        await profile.delete()

        return {"message": "Episode profile deleted successfully"}

View on GitHub (pinned to a7de90d38a)

Solutions

  1. Check the log line 'Failed to update episode profile' for the traceback
  2. Validate speaker_config against current SpeakerProfile records before retrying
  3. Confirm DB health and retry the update
  4. Reload the profile (GET) and reapply the edit to avoid stale-state conflicts
Defensive patterns

Strategy: try-catch

Validate before calling

current = await client.get(f"/api/episode-profiles/{profile_id}")
if current.status_code == 404:
    raise FileNotFoundError(profile_id)  # fail fast before building payload

Try / catch

try:
    await client.put(f"/api/episode-profiles/{profile_id}", json=payload)
except httpx.HTTPStatusError as e:
    if e.response.status_code >= 500:
        await asyncio.sleep(1)
        return await client.put(f"/api/episode-profiles/{profile_id}", json=payload)
    raise

Prevention

When it happens

Trigger: PUT with speaker_config that becomes invalid mid-update, DB connectivity failure during save, or model validation errors not covered by InvalidInputError.

Common situations: Concurrent update/delete races, DB schema drift, speaker profile deleted between the resolve check and the save.

Related errors


AI-assisted analysis of lfnovo/open-notebook@a7de90d38a (2026-08-27). Data as JSON: /api/errors/325ebea79abba1a7. Report an issue: GitHub.