tiangolo/fastapi · warning · UnicornException
Oops! {exc.name} did something. There goes a rainbow...
Error message
Oops! {exc.name} did something. There goes a rainbow... What it means
Raising the custom UnicornException (carrying name="yolo") triggers the registered `@app.exception_handler(UnicornException)`, which returns HTTP 418 with body {"message": "Oops! yolo did something. There goes a rainbow..."}. The message is generated by the handler from exc.name, not by HTTPException, demonstrating FastAPI's custom-exception-handler mechanism.
Source
Thrown at docs_src/handling_errors/tutorial003_py310.py:24
def __init__(self, name: str):
self.name = name
app = FastAPI()
@app.exception_handler(UnicornException)
async def unicorn_exception_handler(request: Request, exc: UnicornException):
return JSONResponse(
status_code=418,
content={"message": f"Oops! {exc.name} did something. There goes a rainbow..."},
)
@app.get("/unicorns/{name}")
async def read_unicorn(name: str):
if name == "yolo":
raise UnicornException(name=name)
return {"unicorn_name": name}
View on GitHub (pinned to 42a41db11f)
Solutions
- Avoid the name "yolo", or accept the 418 if that is the intended demo behavior.
- If adapting to real use, register a handler that returns a meaningful status code (e.g. 400) instead of 418.
- Ensure every custom exception your app raises has a registered handler.
- Add a test asserting the 418 body shape for /unicorns/yolo.
Example fix
# before
if name == "yolo":
raise UnicornException(name=name)
# after (domain-aware)
if name in FORBIDDEN_NAMES:
raise UnicornException(name=name) Defensive patterns
Strategy: validation
Validate before calling
if name == "yolo":
raise ValueError("name 'yolo' is rejected by /unicorns") Type guard
def is_allowed_unicorn(name: str) -> bool:
return name != "yolo" Try / catch
r = client.get(f"/unicorns/{name}")
if r.status_code == 418:
msg = r.json().get("message", "")
if "There goes a rainbow" in msg:
# reserved name hit; choose another
... Prevention
- Block reserved names client-side.
- Register a handler for every custom exception you raise.
- Treat 418 as a domain error, not a transport error.
When it happens
Trigger: GET /unicorns/yolo specifically; any other name returns 200 with the echo body.
Common situations: Clients/probes hitting the reserved name; reusing the UnicornException pattern for real domain errors; forgetting to register an exception_handler so the exception surfaces as 500.
Related errors
AI-assisted analysis of tiangolo/fastapi@42a41db11f (2026-08-04).
Data as JSON: /data/errors/19d3c53225d4536f.json.
Report an issue: GitHub.