{"id":"f25b7ddf4532f854","repo":"pallets/flask","slug":"unable-to-build-urls-outside-an-active-request-wit","errorCode":null,"errorMessage":"Unable to build URLs outside an active request without 'SERVER_NAME' configured. Also configure 'APPLICATION_ROOT' and 'PREFERRED_URL_SCHEME' as needed.","messagePattern":"Unable to build URLs outside an active request without 'SERVER_NAME' configured\\. Also configure 'APPLICATION_ROOT' and 'PREFERRED_URL_SCHEME' as needed\\.","errorType":"exception","errorClass":"RuntimeError","httpStatus":null,"severity":"error","filePath":"src/flask/app.py","lineNumber":1185,"sourceCode":"                    endpoint = f\"{blueprint_name}{endpoint}\"\n                else:\n                    endpoint = endpoint[1:]\n\n            # When in a request, generate a URL without scheme and\n            # domain by default, unless a scheme is given.\n            if _external is None:\n                _external = _scheme is not None\n        else:\n            # If called by helpers.url_for, an app context is active,\n            # use its url_adapter. Otherwise, app.url_for was called\n            # directly, build an adapter.\n            if ctx is not None:\n                url_adapter = ctx.url_adapter\n            else:\n                url_adapter = self.create_url_adapter(None)\n\n            if url_adapter is None:\n                raise RuntimeError(\n                    \"Unable to build URLs outside an active request\"\n                    \" without 'SERVER_NAME' configured. Also configure\"\n                    \" 'APPLICATION_ROOT' and 'PREFERRED_URL_SCHEME' as\"\n                    \" needed.\"\n                )\n\n            # When outside a request, generate a URL with scheme and\n            # domain by default.\n            if _external is None:\n                _external = True\n\n        # It is an error to set _scheme when _external=False, in order\n        # to avoid accidental insecure URLs.\n        if _scheme is not None and not _external:\n            raise ValueError(\"When specifying '_scheme', '_external' must be True.\")\n\n        self.inject_url_defaults(endpoint, values)\n","sourceCodeStart":1167,"sourceCodeEnd":1203,"githubUrl":"https://github.com/pallets/flask/blob/6a2f545bfd8ed31e19066a299296917e034aca58/src/flask/app.py#L1167-L1203","documentation":"Raised in `Flask.url_for()` (src/flask/app.py:1185) when URL building is attempted outside an active request and `create_url_adapter(None)` returns None because `SERVER_NAME` is not configured. Inside a request Flask derives host/scheme/root from the WSGI environ, but outside one it has no way to know the domain, so it needs `SERVER_NAME` (plus optionally `APPLICATION_ROOT` and `PREFERRED_URL_SCHEME`) to construct absolute URLs.","triggerScenarios":"Calling `url_for(...)` (or `app.url_for`) from a plain app context or none at all — e.g. inside a CLI command, background job, scheduler task, or when rendering an email template — with `app.config['SERVER_NAME']` unset.","commonSituations":"Celery/RQ workers and cron jobs generating links for emails; `flask shell` experiments; APScheduler tasks; sitemap or cache-warming scripts; tests calling url_for without `test_request_context`. Developers often hit it after refactoring link generation out of request handlers into background code.","solutions":["Set `app.config['SERVER_NAME'] = 'example.com'` (and `PREFERRED_URL_SCHEME = 'https'`, `APPLICATION_ROOT = '/'` as needed) so URL building works outside requests. Note SERVER_NAME also affects request routing/host matching — set it to your real public host.","If you'd rather not set SERVER_NAME globally, wrap the call in a test request context: `with app.test_request_context(base_url='https://example.com/'): url = url_for(...)`.","In tests, use `with app.test_request_context(): ...` around url_for calls.","If the code actually runs during a request, ensure it executes inside the request (not in a spawned thread that lost the context)."],"exampleFix":"# before (background job)\nlink = url_for(\"confirm_email\", token=token, _external=True)  # RuntimeError\n\n# after\napp.config[\"SERVER_NAME\"] = \"example.com\"\napp.config[\"PREFERRED_URL_SCHEME\"] = \"https\"\nwith app.app_context():\n    link = url_for(\"confirm_email\", token=token, _external=True)","handlingStrategy":"validation","validationCode":"from flask import has_request_context\nif not has_request_context() and not app.config.get('SERVER_NAME'):\n    raise RuntimeError('set SERVER_NAME (and APPLICATION_ROOT / PREFERRED_URL_SCHEME) before url_for outside a request')","typeGuard":"def can_build_external_urls(app) -> bool:\n    from flask import has_request_context\n    return has_request_context() or bool(app.config.get('SERVER_NAME'))","tryCatchPattern":null,"preventionTips":["Set SERVER_NAME, APPLICATION_ROOT, and PREFERRED_URL_SCHEME in config for any app that builds URLs in CLI commands, Celery tasks, or emails","Wrap background-job URL building in `with app.app_context():` after configuring SERVER_NAME","Use `with app.test_request_context():` in tests that call url_for"],"tags":["flask","url-for","server-name","configuration","background-jobs"],"analyzedSha":"6a2f545bfd8ed31e19066a299296917e034aca58","analyzedAt":"2026-07-31T19:13:49.921Z","schemaVersion":2}