The Fix
Upgrade to version 2.0.1 or later.
Based on closed pallets/flask issue #4053 · PR/commit linked
@@ -20,6 +20,9 @@ Unreleased
- Combine URL prefixes when nesting blueprints that were created with
a ``url_prefix`` value. :issue:`4037`
+- Roll back a change to the order that URL matching was done. The
+ URL is again matched after the session is loaded, so the session is
+ available in custom URL converters. :issue:`4053`
@app.route("/test/<installation:installation>")
@flask_login.login_required
def test_route_with_installation(installation):
return flask.jsonify({....})
with app.test_client(use_cookies=True) as client:
r = client.get("/test/123")
Re-run the minimal reproduction on your broken version, then apply the fix and re-run.
Option A — Upgrade to fixed release\nUpgrade to version 2.0.1 or later.\nWhen NOT to use: This fix should not be used if the application relies on the previous behavior of session access during URL matching.\n\n
Why This Fix Works in Production
- Trigger: ctx.push()
- Mechanism: Custom converters cannot access the session during URL matching due to a change in Flask's request context handling
- Why the fix works: Allows custom converters to access the session by matching the request URL after the session is loaded. (first fixed release: 2.0.1).
- If left unfixed, this can cause silent data inconsistencies that propagate (bad cache entries, incorrect downstream decisions).
Why This Breaks in Prod
- Shows up under Python 3.9 in real deployments (not just unit tests).
- Custom converters cannot access the session during URL matching due to a change in Flask's request context handling
- Surfaces as: Traceback (most recent call last):
Proof / Evidence
- GitHub issue: #4053
- Fix PR: https://github.com/pallets/flask/pull/4055
- First fixed release: 2.0.1
- Reproduced locally: No (not executed)
- Last verified: 2026-02-09
- Confidence: 0.95
- Did this fix it?: Yes (upstream fix exists)
- Own content ratio: 0.38
Discussion
High-signal excerpts from the issue thread (symptoms, repros, edge-cases).
“This is because of #3776, which asked to make the matched request available when loading the session object”
“After rolling back #3794, if you're writing a custom session loader and need the endpoint, then you can call: If you need both, you'll need…”
Failure Signature (Search String)
- ctx.push()
Error Message
Stack trace
Error Message
-------------
Traceback (most recent call last):
File "xxxxxxxxxxxxxxxxxxxxx/.tox/py39/lib/python3.9/site-packages/flask/app.py", line 2050, in wsgi_app
ctx.push()
File "xxxxxxxxxxxxxxxxxxxxx/.tox/py39/lib/python3.9/site-packages/flask/ctx.py", line 381, in push
self.match_request()
File "xxxxxxxxxxxxxxxxxxxxx/.tox/py39/lib/python3.9/site-packages/flask/ctx.py", line 349, in match_request
result = self.url_adapter.match(return_rule=True) # type: ignore
File "xxxxxxxxxxxxxxxxxxxxx/.tox/py39/lib/python3.9/site-packages/werkzeug/routing.py", line 1958, in match
rv = rule.match(path, method)
File "xxxxxxxxxxxxxxxxxxxxx/.tox/py39/lib/python3.9/site-packages/werkzeug/routing.py", line 931, in match
value = self._converters[name].to_python(value)
File "xxxxxxxxxxxxxxxxxxxxx/xxxxx/web.py", line 61, in to_python
if not user.is_authenticated:
File "xxxxxxxxxxxxxxxxxxxxx/.tox/py39/lib/python3.9/site-packages/werkzeug/local.py", line 422, in __get__
obj = instance._get_current_object()
File "xxxxxxxxxxxxxxxxxxxxx/.tox/py39/lib/python3.9/site-packages/werkzeug/local.py", line 544, in _get_current_object
return self.__local() # type: ignore
File "xxxxxxxxxxxxxxxxxxxxx/.tox/py39/lib/python3.9/site-packages/flask_login/utils.py", line 26, in <lambda>
current_user = LocalProxy(lambda: _get_user())
File "xxxxxxxxxxxxxxxxxxxxx/.tox/py39/lib/python3.9/si
... (truncated) ...
Minimal Reproduction
@app.route("/test/<installation:installation>")
@flask_login.login_required
def test_route_with_installation(installation):
return flask.jsonify({....})
with app.test_client(use_cookies=True) as client:
r = client.get("/test/123")
Environment
- Python: 3.9
What Broke
Tests fail with AttributeError when accessing session in custom converters.
Why It Broke
Custom converters cannot access the session during URL matching due to a change in Flask's request context handling
Fix Options (Details)
Option A — Upgrade to fixed release Safe default (recommended)
Upgrade to version 2.0.1 or later.
Use when you can deploy the upstream fix. It is usually lower-risk than long-lived workarounds.
Fix reference: https://github.com/pallets/flask/pull/4055
First fixed release: 2.0.1
Last verified: 2026-02-09. Validate in your environment.
When NOT to Use This Fix
- This fix should not be used if the application relies on the previous behavior of session access during URL matching.
Verify Fix
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
| Version | Status |
|---|---|
| 2.0.1 | Fixed |
Related Issues
No related fixes found.
Sources
We don’t republish the full GitHub discussion text. Use the links above for context.