Troubleshooting & FAQ¶
This page focuses on common issues seen when developing and deploying Lilya applications.
Quick checklist¶
Before diving into specific errors, quickly check:
- Are you using the correct app import path (
module:app)? - Are your route paths starting with
/? - Is your
LILYA_SETTINGS_MODULEimport path valid? - If using forms, did you install
python-multipart? - If using optional features (CLI, OpenAPI, etc.), did you install the right extras?
Symptom to root-cause map¶
| Symptom | Likely root cause | First page to check |
|---|---|---|
| 404 for known endpoint | Include prefix mismatch or route precedence | Routing |
| Unexpected auth failures | Permission layering or middleware ordering | Permissions |
| Wrong config values at runtime | Settings precedence misunderstanding | Settings |
Body read errors (Stream consumed) |
Mixed streaming and buffered body access | Request |
| Startup/shutdown issues | Lifespan hook composition | Lifecycle |
Route returns 404 but I expected a match¶
Most common causes:
- Route path does not start with
/. - Route is mounted under an
Includeprefix you forgot. - You expected path params on
Include(not supported). - Your path has a trailing slash mismatch and
redirect_slashes=False.
Also verify route priority if multiple routes can match.
I get Paths must start with '/'¶
Path and WebSocketPath must start with /.
Correct:
Incorrect:
I get Either 'app=...', or 'routes=...', or 'namespace=...' must be specified¶
This comes from Include(...).
At least one of these must be provided:
app=...routes=[...]namespace="..."
WebSocket fails with connection state/runtime errors¶
If you receive errors like:
WebSocket is not connected. Need to call "accept" first.
It usually means you tried to send/receive text/json/bytes before await websocket.accept().
Always accept first:
async def ws(websocket):
await websocket.accept()
data = await websocket.receive_text()
await websocket.send_text(data)
Form parsing fails¶
If parsing form or multipart data fails early, ensure python-multipart is installed.
Lilya requires it for:
await request.form()- multipart file uploads
Stream consumed when reading body¶
request.stream() consumes the body as chunks.
After consuming stream chunks, calling request.body(), request.json(), or request.form() is not valid for the same request body flow.
Choose one approach per request:
stream()for chunk processingbody()/json()/form()for buffered parsing
Static files return 404 unexpectedly¶
Check these first:
directoryexists and is readable.- Requested file path is really under the configured directory.
- If you expect directory behavior, set
html=True. - If you chain multiple
StaticFiles, usefall_through=Truefor non-final layers.
Runtime error when adding middleware/permissions dynamically¶
After startup, middleware and permissions are considered locked for safety.
Typical errors:
Middlewares cannot be added once the application has started.Permissions cannot be added once the application has started.
Register middleware/permissions during app setup, not after serving requests.
Reverse lookup fails (NoMatchFound)¶
Check:
- Route has a
name. - All required path params were provided.
- Nested includes use namespaced names (
prefix:name).
Why does caching seem local in multi-worker deployments?¶
InMemoryCache is process-local. In multi-worker setups, each worker has its own cache memory.
Use a shared backend (for example Redis) when you need cache consistency across workers.
Settings do not look applied¶
Remember settings precedence:
- Parameters passed directly to
Lilya(...) settings_modulepassed to app instanceLILYA_SETTINGS_MODULE- Lilya defaults
If a value looks ignored, check if it is being overridden at a higher precedence level.
Still blocked?¶
When reporting an issue, include:
- Lilya version
- Python version
- ASGI server and version
- minimal reproducible route/app
- full traceback
That usually reduces turnaround time significantly.
See also¶
- Architecture Overview for route and middleware flow.
- Routing for matching and include composition.
- Dependencies for scope and override behavior.
- Exceptions for handler precedence and exception types.