tiangolo/fastapi · error · HTTPException
Item already exists
Error message
Item already exists
What it means
Raised by POST /items/ when the submitted Item's id already exists as a key in fake_db, returning HTTP 409 Conflict. It enforces uniqueness of item ids and prevents duplicate creation.
Source
Thrown at docs_src/app_testing/app_b_an_py310/main.py:36
title: str
description: str | None = None
@app.get("/items/{item_id}", response_model=Item)
async def read_main(item_id: str, x_token: Annotated[str, Header()]):
if x_token != fake_secret_token:
raise HTTPException(status_code=400, detail="Invalid X-Token header")
if item_id not in fake_db:
raise HTTPException(status_code=404, detail="Item not found")
return fake_db[item_id]
@app.post("/items/")
async def create_item(item: Item, x_token: Annotated[str, Header()]) -> Item:
if x_token != fake_secret_token:
raise HTTPException(status_code=400, detail="Invalid X-Token header")
if item.id in fake_db:
raise HTTPException(status_code=409, detail="Item already exists")
fake_db[item.id] = item.model_dump()
return item
View on GitHub (pinned to 42a41db11f)
Solutions
- Use a unique id for each create (e.g. uuid4).
- On 409, GET the existing item instead of re-posting.
- Make the client idempotent by checking existence before creating.
Example fix
# before item_id = "foo" # already exists # after import uuid item_id = str(uuid.uuid4())
Defensive patterns
Strategy: validation
Validate before calling
# Generate a unique id to avoid collisions
import uuid
payload = {"id": str(uuid.uuid4()), "title": "Baz"} Type guard
def is_unique_id(new_id: str, existing: set[str]) -> bool:
return new_id not in existing Try / catch
resp = client.post("/items/", json=payload, headers=auth)
if resp.status_code == 409:
# already exists; fetch instead
client.get(f"/items/{payload['id']}", headers=auth) Prevention
- Use server- or UUID-generated ids for creates.
- Make POST retries idempotent with an idempotency key.
- On 409, switch to a GET/update flow.
When it happens
Trigger: POST /items/ with a JSON body whose id field equals an existing key ("foo" or "bar", or any previously created id).
Common situations: Retrying a POST after a timeout that actually succeeded; duplicate-submit; seeding scripts run twice; client generating ids that collide.
Related errors
AI-assisted analysis of tiangolo/fastapi@42a41db11f (2026-08-04).
Data as JSON: /data/errors/4f570283ed13aa64.json.
Report an issue: GitHub.