pallets/flask · error · RuntimeError
Session backend did not open a session.
Error message
Session backend did not open a session.
What it means
Raised as a RuntimeError by `session_transaction()` when `app.session_interface.open_session(app, request)` returns None inside the temporary test request context. Flask's default SecureCookieSessionInterface always returns a session object, so this indicates a custom or third-party session interface that failed to produce one — typically due to missing configuration or backend connectivity.
Source
Thrown at src/flask/testing.py:168
request context and since session handling could depend on
request variables this function accepts the same arguments as
:meth:`~flask.Flask.test_request_context` which are directly
passed through.
"""
if self._cookies is None:
raise TypeError(
"Cookies are disabled. Create a client with 'use_cookies=True'."
)
app = self.application
ctx = app.test_request_context(*args, **kwargs)
self._add_cookies_to_wsgi(ctx.request.environ)
with ctx:
sess = app.session_interface.open_session(app, ctx.request)
if sess is None:
raise RuntimeError("Session backend did not open a session.")
yield sess
resp = app.response_class()
if app.session_interface.is_null_session(sess):
return
with ctx:
app.session_interface.save_session(app, sess, resp)
self._update_cookies_from_response(
ctx.request.host.partition(":")[0],
ctx.request.path,
resp.headers.getlist("Set-Cookie"),
)
def _copy_environ(self, other: WSGIEnvironment) -> WSGIEnvironment:
out = {**self.environ_base, **other}View on GitHub ↗ (pinned to 6a2f545bfd)
Solutions
- Set `app.config['SECRET_KEY']` in your test setup before creating the client.
- Ensure the session backend (Redis, DB, etc.) used by your session interface is reachable in the test environment, or swap in the default cookie session interface for tests.
- Fix a custom `SessionInterface.open_session` to return a `NullSession`/new session rather than None when the store is empty.
Example fix
# before
app = Flask(__name__)
app.session_interface = MyRedisSessionInterface() # redis down in CI
# after
app = Flask(__name__)
app.config["SECRET_KEY"] = "test"
if app.testing:
pass # keep default cookie sessions in tests
else:
app.session_interface = MyRedisSessionInterface() Defensive patterns
Strategy: validation
Validate before calling
app.secret_key = 'test-secret' # required for the default cookie session backend
with app.test_client() as client:
with client.session_transaction() as sess:
sess['k'] = 'v' Try / catch
try:
with client.session_transaction() as sess:
...
except RuntimeError as e:
if 'did not open a session' in str(e):
# secret_key missing or custom session interface returned None
raise Prevention
- Set app.secret_key (or SECRET_KEY config) in the test app factory before using session_transaction
- If you use a custom session interface, ensure open_session never returns None in testing
- Verify session config in a conftest fixture so every test gets a working backend
When it happens
Trigger: Using `with client.session_transaction():` while `app.session_interface` is a custom interface whose `open_session` returns None — e.g. it requires `SECRET_KEY` or a live backing store (Redis, database) that isn't available in the test environment. (With the default interface and no SECRET_KEY, older Flask versions returned None here; modern default returns a NullSession instead.)
Common situations: Server-side session extensions (Flask-Session and similar) configured against a Redis/memcached instance not running in CI; custom session interfaces that return None on missing config instead of a NullSession; forgetting to set `SECRET_KEY` in the test app config with an interface that gates on it.
Related errors
- Cookies are disabled. Create a client with 'use_cookies=True
- The session is unavailable because no secret key was set. S
- Cannot pop this context ({self!r}), it is not pushed.
- Tag '{key}' is already registered.
- Cannot nest client invocations
AI-assisted analysis of pallets/flask@6a2f545bfd (2026-07-31).
Data as JSON: /data/errors/6d1f2a720132954d.json.
Report an issue: GitHub ↗.