{"record":{"id":"5f46f771e7b8e454","repo":"tiangolo/fastapi","slug":"hero-not-found-5f46f7","errorCode":null,"errorMessage":"Hero not found","messagePattern":"Hero not found","errorType":"http","errorClass":"HTTPException","httpStatus":404,"severity":"error","filePath":"docs_src/sql_databases/tutorial002_an_py310.py","lineNumber":79,"sourceCode":"    session.refresh(db_hero)\n    return db_hero\n\n\n@app.get(\"/heroes/\", response_model=list[HeroPublic])\ndef read_heroes(\n    session: SessionDep,\n    offset: int = 0,\n    limit: Annotated[int, Query(le=100)] = 100,\n):\n    heroes = session.exec(select(Hero).offset(offset).limit(limit)).all()\n    return heroes\n\n\n@app.get(\"/heroes/{hero_id}\", response_model=HeroPublic)\ndef read_hero(hero_id: int, session: SessionDep):\n    hero = session.get(Hero, hero_id)\n    if not hero:\n        raise HTTPException(status_code=404, detail=\"Hero not found\")\n    return hero\n\n\n@app.patch(\"/heroes/{hero_id}\", response_model=HeroPublic)\ndef update_hero(hero_id: int, hero: HeroUpdate, session: SessionDep):\n    hero_db = session.get(Hero, hero_id)\n    if not hero_db:\n        raise HTTPException(status_code=404, detail=\"Hero not found\")\n    hero_data = hero.model_dump(exclude_unset=True)\n    hero_db.sqlmodel_update(hero_data)\n    session.add(hero_db)\n    session.commit()\n    session.refresh(hero_db)\n    return hero_db\n\n\n@app.delete(\"/heroes/{hero_id}\")\ndef delete_hero(hero_id: int, session: SessionDep):","sourceCodeStart":61,"sourceCodeEnd":97,"githubUrl":"https://github.com/tiangolo/fastapi/blob/3e8d1526d83a90aaf7d6eb6dc682bf150f180b25/docs_src/sql_databases/tutorial002_an_py310.py#L61-L97","documentation":"Application-defined HTTPException in the read_hero GET endpoint of the multi-model tutorial (Annotated style). After session.get(Hero, hero_id) returns None for a missing primary key, the handler raises HTTPException(status_code=404, detail=\"Hero not found\"); FastAPI turns that into a 404 response with {\"detail\":\"Hero not found\"}.","triggerScenarios":"GET /heroes/{hero_id} against an ID that has no Hero row (deleted, never created, or wrong DB file).","commonSituations":"Client requests a hero ID obtained from a stale list or external source; database.db reset; the row was deleted after being listed.","solutions":["Validate the ID exists before the request.","Point the app at the correct seeded SQLite database file.","Have the client treat a 404 as a normal not-found.","Return None / 204 from the endpoint if absence is not exceptional."],"exampleFix":"// before\n@app.get(\"/heroes/{hero_id}\", response_model=HeroPublic)\ndef read_hero(hero_id: int, session: SessionDep):\n    hero = session.get(Hero, hero_id)\n    if not hero:\n        raise HTTPException(status_code=404, detail=\"Hero not found\")\n    return hero\n\n// after\n@app.get(\"/heroes/{hero_id}\", response_model=HeroPublic | None)\ndef read_hero(hero_id: int, session: SessionDep):\n    return session.get(Hero, hero_id)","handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"import httpx\ntry:\n    r = httpx.get(f\"http://localhost:8000/heroes/{hero_id}\")\n    r.raise_for_status()\nexcept httpx.HTTPStatusError as e:\n    if e.response.status_code == 404:\n        hero = None\n    else:\n        raise","preventionTips":["Validate the ID against the known list before requesting it.","Keep database.db persistent and seeded.","Return Optional response_model if a missing row is not exceptional.","Handle 404 explicitly on the client to avoid crashes."],"tags":["sqlmodel","http-404","sql-databases","rest","fastapi"],"backgroundTag":null,"analyzedSha":"3e8d1526d83a90aaf7d6eb6dc682bf150f180b25","analyzedAt":"2026-08-11T02:34:52.986Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}