{"record":{"id":"ffea8397daeaa3ce","repo":"tiangolo/fastapi","slug":"hero-not-found-ffea83","errorCode":null,"errorMessage":"Hero not found","messagePattern":"Hero not found","errorType":"http","errorClass":"HTTPException","httpStatus":404,"severity":"error","filePath":"docs_src/sql_databases/tutorial002_py310.py","lineNumber":76,"sourceCode":"    session.refresh(db_hero)\n    return db_hero\n\n\n@app.get(\"/heroes/\", response_model=list[HeroPublic])\ndef read_heroes(\n    session: Session = Depends(get_session),\n    offset: int = 0,\n    limit: int = Query(default=100, le=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: Session = Depends(get_session)):\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(\n    hero_id: int, hero: HeroUpdate, session: Session = Depends(get_session)\n):\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","sourceCodeStart":58,"sourceCodeEnd":94,"githubUrl":"https://github.com/tiangolo/fastapi/blob/3e8d1526d83a90aaf7d6eb6dc682bf150f180b25/docs_src/sql_databases/tutorial002_py310.py#L58-L94","documentation":"Application-defined HTTPException in the read_hero GET endpoint of the multi-model tutorial (non-Annotated). When session.get(Hero, hero_id) returns None the handler raises HTTPException(status_code=404, detail=\"Hero not found\"), which FastAPI returns as a 404 with {\"detail\":\"Hero not found\"}.","triggerScenarios":"GET /heroes/{hero_id} for a primary key that has no Hero row (deleted, never created, wrong DB).","commonSituations":"Stale client ID; empty/reset database.db; row deleted between list and detail calls; wrong SQLite file.","solutions":["Validate the ID before requesting it.","Ensure the SQLite file is seeded and correct.","Have the client treat 404 as expected.","Return None / 204 instead of raising if absence is normal."],"exampleFix":"// before\n@app.get(\"/heroes/{hero_id}\", response_model=HeroPublic)\ndef read_hero(hero_id: int, session: Session = Depends(get_session)):\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: Session = Depends(get_session)):\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()\n    hero = r.json()\nexcept httpx.HTTPStatusError as e:\n    if e.response.status_code == 404:\n        hero = None\n    else:\n        raise","preventionTips":["Request only IDs returned by the list endpoint.","Keep the database persistent and seeded.","Return Optional/None if absence is expected.","Treat 404 as a normal not-found in client code."],"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"}