{"record":{"id":"6d1f2a720132954d","repo":"pallets/flask","slug":"session-backend-did-not-open-a-session","errorCode":null,"errorMessage":"Session backend did not open a session.","messagePattern":"Session backend did not open a session\\.","errorType":"exception","errorClass":"RuntimeError","httpStatus":null,"severity":"error","filePath":"src/flask/testing.py","lineNumber":168,"sourceCode":"        request context and since session handling could depend on\n        request variables this function accepts the same arguments as\n        :meth:`~flask.Flask.test_request_context` which are directly\n        passed through.\n        \"\"\"\n        if self._cookies is None:\n            raise TypeError(\n                \"Cookies are disabled. Create a client with 'use_cookies=True'.\"\n            )\n\n        app = self.application\n        ctx = app.test_request_context(*args, **kwargs)\n        self._add_cookies_to_wsgi(ctx.request.environ)\n\n        with ctx:\n            sess = app.session_interface.open_session(app, ctx.request)\n\n        if sess is None:\n            raise RuntimeError(\"Session backend did not open a session.\")\n\n        yield sess\n        resp = app.response_class()\n\n        if app.session_interface.is_null_session(sess):\n            return\n\n        with ctx:\n            app.session_interface.save_session(app, sess, resp)\n\n        self._update_cookies_from_response(\n            urlsplit(ctx.request.host_url).hostname or \"localhost\",\n            ctx.request.path,\n            resp.headers.getlist(\"Set-Cookie\"),\n        )\n\n    def _copy_environ(self, other: WSGIEnvironment) -> WSGIEnvironment:\n        out = {**self.environ_base, **other}","sourceCodeStart":150,"sourceCodeEnd":186,"githubUrl":"https://github.com/pallets/flask/blob/3596b1ab61cea85edb8970e83ff61daa073facf8/src/flask/testing.py#L150-L186","documentation":"In session_transaction, Flask calls app.session_interface.open_session(app, ctx.request). If that returns None (the interface could not/ would not open a session - e.g. SecureCookieSessionInterface with no secret key, or a custom interface whose open_session returns None), the method raises RuntimeError. This is the session-backend equivalent of the NullSession secret-key failure, surfaced at test time.","triggerScenarios":"Running session_transaction without app.secret_key set (SecureCookieSessionInterface.open_session returns None when secret_key is falsy); a custom SessionInterface whose open_session returns None on a malformed cookie or unsupported request.","commonSituations":"Test app factory forgot to set secret_key; switched to a custom session backend whose open_session has a None path; cookie sent in the test is unsigned/expired.","solutions":["Set app.secret_key before session_transaction (most common cause).","If using a custom SessionInterface, ensure open_session always returns a session object (never None) for valid requests, or raise a clearer error inside it.","In tests, build the app with a known secret_key and a stable session interface."],"exampleFix":"// before\napp = Flask(__name__)\nwith app.test_client(use_cookies=True) as c:\n    with c.session_transaction() as sess:  # raises\n        sess['k'] = 1\n\n// after\napp = Flask(__name__)\napp.secret_key = 'test'\nwith app.test_client(use_cookies=True) as c:\n    with c.session_transaction() as sess:\n        sess['k'] = 1","handlingStrategy":"validation","validationCode":"def session_can_open(app, request):\n    sess = app.session_interface.open_session(app, request)\n    if sess is None:\n        if not app.secret_key:\n            raise RuntimeError('set app.secret_key so the session backend can open a session')\n        raise RuntimeError('session_interface.open_session returned None')\n    return sess\n","typeGuard":null,"tryCatchPattern":"try:\n    with client.session_transaction() as s:\n        s['k'] = 1\nexcept RuntimeError as e:\n    if 'did not open a session' in str(e):\n        app.secret_key = 'test'  # fix and retry in tests\n        raise","preventionTips":["Set app.secret_key in the test app factory.","Custom SessionInterface.open_session must never return None for valid requests.","Add a startup self-check that opens a dummy session."],"tags":["flask","testing","session","secret-key","configuration"],"backgroundTag":null,"analyzedSha":"3596b1ab61cea85edb8970e83ff61daa073facf8","analyzedAt":"2026-08-11T20:11:52.622Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}