jamiepine/voicebox · error · HTTPException

Story or generation not found

Error message

Story or generation not found

What it means

Returned by POST /stories/{story_id}/items when stories.add_item_to_story returns falsy (HTTP 404). The single guard covers two distinct miss conditions: the story_id does not exist, or the generation referenced in StoryItemCreate does not exist. The message combines both because the service returns one falsy signal for either.

Solutions

  1. Verify both story_id (GET /stories/{story_id}) and the referenced generation exist before adding.
  2. Refresh the generations list to obtain a current generation_id.
  3. If the message is ambiguous in the UI, pre-check both entities to disambiguate.
  4. Avoid holding generation ids long-term; re-fetch before use.

Example fix

// before
await api.post(`/stories/${sid}/items`, { generation_id: gen });

// after
if (!await storyExists(sid) || !await generationExists(gen))
  throw new NotFoundError('story or generation');
await api.post(`/stories/${sid}/items`, { generation_id: gen });
Defensive patterns

Strategy: validation

Validate before calling

async function canAddItem(storyId, generationId) {
  const [s, g] = await Promise.all([
    fetch(`/api/stories/${encodeURIComponent(storyId)}`),
    fetch(`/api/generations/${encodeURIComponent(generationId)}`),
  ]);
  return s.ok && g.ok;
}

Type guard

function isItemCreate(v) { return !!v && typeof v.generation_id === 'string'; }

Try / catch

try { await api.post(`/stories/${sid}/items`, payload); }
catch (e) { if (e.response?.status === 404) disambiguateStoryOrGeneration(sid, payload.generation_id); throw e; }

Prevention

When it happens

Trigger: Adding a generation to a non-existent story, or referencing a generation_id that does not exist (wrong id, deleted, or belongs to another scope). The handler cannot distinguish which from the return value alone.

Common situations: Generation was deleted between creation and adding to a story. Story_id from a stale list. Generation_id copied from a different environment.

Related errors


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

Appendix: source

Thrown at backend/routes/stories.py:81

    db: Session = Depends(get_db),
):
    """Delete a story."""
    success = await stories.delete_story(story_id, db)
    if not success:
        raise HTTPException(status_code=404, detail="Story not found")
    return {"message": "Story deleted successfully"}


@router.post("/stories/{story_id}/items", response_model=models.StoryItemDetail)
async def add_story_item(
    story_id: str,
    data: models.StoryItemCreate,
    db: Session = Depends(get_db),
):
    """Add a generation to a story."""
    item = await stories.add_item_to_story(story_id, data, db)
    if not item:
        raise HTTPException(status_code=404, detail="Story or generation not found")
    return item


@router.delete("/stories/{story_id}/items/{item_id}")
async def remove_story_item(
    story_id: str,
    item_id: str,
    db: Session = Depends(get_db),
):
    """Remove a story item from a story."""
    success = await stories.remove_item_from_story(story_id, item_id, db)
    if not success:
        raise HTTPException(status_code=404, detail="Story item not found")
    return {"message": "Item removed successfully"}


@router.put("/stories/{story_id}/items/times")
async def update_story_item_times(

View on GitHub (pinned to 51f49dea19)