Skip to main content
Run the entry point directly to see the full traceback:
Discovery is strict — a broken module under models/, services/ or routes/ stops the app rather than being silently dropped. Set FEATHER_LENIENT_DISCOVERY=1 to warn and continue while you fix it.
Either DEBUG=False and feather build was never run, or static/dist/ is missing or outdated. Always run feather build before deploying.If only the framework components are unstyled, check the Tailwind @source path. See Upgrading.
With the thread backend, Flask’s auto-reloader restarts the process on every file change and kills running threads. Set FLASK_DEBUG=0 in .env, or use JOB_BACKEND=sync during development if you need debug mode.
The redirect URI is being built from the request Host header. Set OAUTH_CALLBACK_URL to the exact callback you registered with Google, and TRUSTED_HOSTS to the hostnames you serve. Confirm your proxy forwards X-Forwarded-Proto — see TLS and the proxy headers.
Flask-Login caches the current user on g for the lifetime of an application context. A fixture holding one app.app_context() open across several test clients resolves every request to the first user loaded. See Test database.
@rate_limit keeps counters in the process. Under gunicorn --workers 4 a limit of ten per minute is really forty. Use Flask-Limiter with Redis — see Rate limiting.

Tail the logs

In production:
Every response carries a request ID header, and every log line carries the matching request_id. See Request tracking.