jamiepine/voicebox · error · HTTPException

Generation not found

Error message

Generation not found

What it means

HTTP 404 raised by POST /effects/preview/{generation_id} when the DBGeneration lookup by id returns no row. The handler queries db.query(DBGeneration).filter_by(id=generation_id).first() and raises 404 'Generation not found' on a miss. This check runs before any status or effects validation.

Source

Thrown at backend/routes/effects.py:27

from sqlalchemy.orm import Session

from .. import config, models
from ..services import history
from ..database import Generation as DBGeneration, get_db

router = APIRouter()


@router.post("/effects/preview/{generation_id}")
async def preview_effects(
    generation_id: str,
    data: models.ApplyEffectsRequest,
    db: Session = Depends(get_db),
):
    """Apply effects to a generation's clean audio and stream back without saving."""
    gen = db.query(DBGeneration).filter_by(id=generation_id).first()
    if not gen:
        raise HTTPException(status_code=404, detail="Generation not found")
    if (gen.status or "completed") != "completed":
        raise HTTPException(status_code=400, detail="Generation is not completed")

    from ..services import versions as versions_mod
    from ..utils.effects import apply_effects, validate_effects_chain
    from ..utils.audio import load_audio

    chain_dicts = [e.model_dump() for e in data.effects_chain]
    error = validate_effects_chain(chain_dicts)
    if error:
        raise HTTPException(status_code=400, detail=error)

    all_versions = versions_mod.list_versions(generation_id, db)
    clean_version = next((v for v in all_versions if v.effects_chain is None), None)
    source_path = clean_version.audio_path if clean_version else gen.audio_path
    resolved_source_path = config.resolve_storage_path(source_path)
    if resolved_source_path is None or not resolved_source_path.exists():
        raise HTTPException(status_code=404, detail="Source audio file not found")

View on GitHub (pinned to 51f49dea19)

Solutions

  1. Confirm the generation_id exists in the generations list before opening the effects preview.
  2. Copy the ID from a recent generation response, not from a cached/older one.
  3. On 404, refresh the generations list and discard the stale reference.

Example fix

// before
await fetch(`/effects/preview/${genId}`, { method:'POST', body: JSON.stringify(payload) });
// after
const gens = await fetch('/generations').then(r => r.json());
if (!gens.some(g => g.id === genId)) { await refreshGenerations(); return; }
await fetch(`/effects/preview/${genId}`, { method:'POST', body: JSON.stringify(payload) });
Defensive patterns

Strategy: validation

Validate before calling

const gens = await fetch('/generations').then(r => r.json());
if (!gens.some(g => g.id === generationId)) throw new Error('generation missing');

Type guard

function isGenerationList(v): v is Array<{ id: string }> { return Array.isArray(v) && v.every(g => typeof g?.id === 'string'); }

Try / catch

const r = await fetch(`/effects/preview/${generationId}`, { method:'POST', body: JSON.stringify(data) });
if (r.status === 404) { await refreshGenerations(); }

Prevention

When it happens

Trigger: POST /effects/preview/{generation_id} with a generation_id that was never created, was deleted, or is malformed.

Common situations: Previewing effects for a generation from a stale list; using a clip/voice ID instead of a generation ID; generation pruned by cleanup.

Related errors


AI-assisted analysis of jamiepine/voicebox@51f49dea19 (2026-08-12). Data as JSON: /api/errors/979b216d0f76795c. Report an issue: GitHub.