Jump to solution
Verify

The Fix

Upgrade to version 0.15.0 or later.

Based on closed Kludex/uvicorn issue #984 · PR/commit linked

Production note: Most teams hit this during upgrades or environment changes. Roll out with a canary and smoke critical endpoints (health, OpenAPI/docs) before 100%.

Jump to Verify Open PR/Commit
@@ -37,6 +37,13 @@ Options: --reload-dir PATH Set reload directories explicitly, instead of using the current working directory. + --reload-include TEXT Set glob patterns to include while watching + for files. Includes '*.py' by default, which + can be overridden in reload-excludes.
repro.py
import os import sys import uvicorn from uvicorn.supervisors.watchgodreload import CustomWatcher ignored = { "templates", "static", "staticfiles", "compose", ".ipython", "bin", ".pytest_cache", ".idea", "media", "htmlcov", "docs", "locale", "requirements", } class WatchgodWatcher(CustomWatcher): def __init__(self, *args, **kwargs): self.ignored_dirs.update(ignored) super(WatchgodWatcher, self).__init__(*args, **kwargs) uvicorn.supervisors.watchgodreload.CustomWatcher = WatchgodWatcher if __name__ == "__main__": sys.path.insert(0, os.path.abspath("/app")) uvicorn.run("config.asgi:application", host="0.0.0.0", reload=True)
verify
Re-run the minimal reproduction on your broken version, then apply the fix and re-run.
fix.md
Option A — Upgrade to fixed release\nUpgrade to version 0.15.0 or later.\nWhen NOT to use: Do not use this fix if your application requires strict reload behavior without exclusions.\n\nOption C — Workaround\nis to create another level of a directory to isolate the SQLite file, (which I feel not a good idea)\nWhen NOT to use: Do not use this fix if your application requires strict reload behavior without exclusions.\n\n

Why This Fix Works in Production

  • Trigger: * `--ignore-dir frontend`: would enable me to ignore changes to frontend source code that are triggering a large number of reloads of my uvicorn app, despite…
  • Mechanism: The application reload mechanism did not allow excluding specific directories or including specific files
  • Why the fix works: Introduces configurable reload options for Uvicorn, allowing users to specify which files to include or exclude from triggering reloads. (first fixed release: 0.15.0).
Production impact:
  • If left unfixed, the same config can fail only in production (env differences), causing startup failures or partial feature outages.

Why This Breaks in Prod

  • The application reload mechanism did not allow excluding specific directories or including specific files
  • Production symptom (often without a traceback): * `--ignore-dir frontend`: would enable me to ignore changes to frontend source code that are triggering a large number of reloads of my uvicorn app, despite those changes being irrelevant;

Proof / Evidence

  • GitHub issue: #984
  • Fix PR: https://github.com/kludex/uvicorn/pull/820
  • First fixed release: 0.15.0
  • Reproduced locally: No (not executed)
  • Last verified: 2026-02-09
  • Confidence: 0.75
  • Did this fix it?: Yes (upstream fix exists)
  • Own content ratio: 0.56

Discussion

High-signal excerpts from the issue thread (symptoms, repros, edge-cases).

“For anyone looking to monkey patch uvicorn with watchgod for the moment, you can do something like this: https://github.com/pydanny/cookiecutter-django/pull/3168 Although that's only dirs only, there's…”
@Andrew-Chen-Wang · 2021-05-28 · source
“I'd be in favor of #820 as well, I'll personally also put that on hold while we try finish coverage and mypy”
@euri10 · 2021-06-10 · source
“Vote for #820 And it would be great if uvicorn.supervisors.watchgodreload.DefaultWatcher.ignored_file_regexes had image, video and log files in it. Cause it's expected behavior for servers to…”
@slavaGanzin · 2021-07-10 · source
“this is https://github.com/encode/uvicorn/pull/820 I was talking about, happy to see someone revive it if needed”
@euri10 · 2021-03-09 · source

Failure Signature (Search String)

  • * `--ignore-dir frontend`: would enable me to ignore changes to frontend source code that are triggering a large number of reloads of my uvicorn app, despite those changes being
  • - --ignore-dir frontend: would enable me to ignore changes to frontend
Copy-friendly signature
signature.txt
Failure Signature ----------------- * `--ignore-dir frontend`: would enable me to ignore changes to frontend source code that are triggering a large number of reloads of my uvicorn app, despite those changes being irrelevant; - --ignore-dir frontend: would enable me to ignore changes to frontend

Error Message

Signature-only (no traceback captured)
error.txt
Error Message ------------- * `--ignore-dir frontend`: would enable me to ignore changes to frontend source code that are triggering a large number of reloads of my uvicorn app, despite those changes being irrelevant; - --ignore-dir frontend: would enable me to ignore changes to frontend

Minimal Reproduction

repro.py
import os import sys import uvicorn from uvicorn.supervisors.watchgodreload import CustomWatcher ignored = { "templates", "static", "staticfiles", "compose", ".ipython", "bin", ".pytest_cache", ".idea", "media", "htmlcov", "docs", "locale", "requirements", } class WatchgodWatcher(CustomWatcher): def __init__(self, *args, **kwargs): self.ignored_dirs.update(ignored) super(WatchgodWatcher, self).__init__(*args, **kwargs) uvicorn.supervisors.watchgodreload.CustomWatcher = WatchgodWatcher if __name__ == "__main__": sys.path.insert(0, os.path.abspath("/app")) uvicorn.run("config.asgi:application", host="0.0.0.0", reload=True)

What Broke

Unnecessary reloads occurred due to changes in irrelevant files, impacting application performance.

Why It Broke

The application reload mechanism did not allow excluding specific directories or including specific files

Fix Options (Details)

Option A — Upgrade to fixed release Safe default (recommended)

Upgrade to version 0.15.0 or later.

When NOT to use: Do not use this fix if your application requires strict reload behavior without exclusions.

Use when you can deploy the upstream fix. It is usually lower-risk than long-lived workarounds.

Option C — Workaround Temporary workaround

is to create another level of a directory to isolate the SQLite file, (which I feel not a good idea)

When NOT to use: Do not use this fix if your application requires strict reload behavior without exclusions.

Use only if you cannot change versions today. Treat this as a stopgap and remove once upgraded.

Option D — Guard side-effects with OnceOnly Guardrail for side-effects

Mitigate duplicate external side-effects under retries/timeouts/agent loops by gating the operation before calling external systems.

  • Place OnceOnly between your code/agent and real side-effects (Stripe, emails, CRM, APIs).
  • Use a stable key per side-effect (e.g., customer_id + action + idempotency_key).
  • Fail-safe: configure fail-open vs fail-closed based on blast radius and spend risk.
Show example snippet (optional)
onceonly.py
from onceonly import OnceOnly import os once = OnceOnly(api_key=os.environ["ONCEONLY_API_KEY"], fail_open=True) # Stable idempotency key per real side-effect. # Use a request id / job id / webhook delivery id / Stripe event id, etc. event_id = "evt_..." # replace key = f"stripe:webhook:{event_id}" res = once.check_lock(key=key, ttl=3600) if res.duplicate: return {"status": "already_processed"} # Safe to execute the side-effect exactly once. handle_event(event_id)

See OnceOnly SDK

When NOT to use: Do not use this to hide logic bugs or data corruption. Use it to block duplicate external side-effects and enforce tool permissions/spend caps.

Fix reference: https://github.com/kludex/uvicorn/pull/820

First fixed release: 0.15.0

Last verified: 2026-02-09. Validate in your environment.

Get updates

We publish verified fixes weekly. No spam.

Subscribe

When NOT to Use This Fix

  • Do not use this fix if your application requires strict reload behavior without exclusions.
  • Do not use this to hide logic bugs or data corruption. Use it to block duplicate external side-effects and enforce tool permissions/spend caps.

Verify Fix

verify
Re-run the minimal reproduction on your broken version, then apply the fix and re-run.

Did This Fix Work in Your Case?

Quick signal helps us prioritize which fixes to verify and improve.

Prevention

  • Capture the exact failing error string in logs and tests so you can reproduce via a minimal script.
  • Pin production dependencies and upgrade only with a reproducible test that hits the failing path.

Version Compatibility Table

VersionStatus
0.15.0 Fixed

Related Issues

No related fixes found.

Sources

We don’t republish the full GitHub discussion text. Use the links above for context.