{"id":"9d8c7bc874d02585","repo":"pallets/flask","slug":"name-may-not-be-empty","errorCode":null,"errorMessage":"'name' may not be empty.","messagePattern":"'name' may not be empty\\.","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"src/flask/sansio/blueprints.py","lineNumber":196,"sourceCode":"        static_folder: str | os.PathLike[str] | None = None,\n        static_url_path: str | None = None,\n        template_folder: str | os.PathLike[str] | None = None,\n        url_prefix: str | None = None,\n        subdomain: str | None = None,\n        url_defaults: dict[str, t.Any] | None = None,\n        root_path: str | None = None,\n        cli_group: str | None = _sentinel,  # type: ignore[assignment]\n    ):\n        super().__init__(\n            import_name=import_name,\n            static_folder=static_folder,\n            static_url_path=static_url_path,\n            template_folder=template_folder,\n            root_path=root_path,\n        )\n\n        if not name:\n            raise ValueError(\"'name' may not be empty.\")\n\n        if \".\" in name:\n            raise ValueError(\"'name' may not contain a dot '.' character.\")\n\n        self.name = name\n        self.url_prefix = url_prefix\n        self.subdomain = subdomain\n        self.deferred_functions: list[DeferredSetupFunction] = []\n\n        if url_defaults is None:\n            url_defaults = {}\n\n        self.url_values_defaults = url_defaults\n        self.cli_group = cli_group\n        self._blueprints: list[tuple[Blueprint, dict[str, t.Any]]] = []\n\n    def _check_setup_finished(self, f_name: str) -> None:\n        if self._got_registered_once:","sourceCodeStart":178,"sourceCodeEnd":214,"githubUrl":"https://github.com/pallets/flask/blob/6a2f545bfd8ed31e19066a299296917e034aca58/src/flask/sansio/blueprints.py#L178-L214","documentation":"A ValueError from `Blueprint.__init__` (src/flask/sansio/blueprints.py:195-196). The blueprint `name` is the first positional argument and becomes the prefix for every endpoint the blueprint registers (`name.view`) and the key in `app.blueprints`; an empty or falsy name would produce unaddressable endpoints and an unusable registry key, so Flask rejects it at construction time.","triggerScenarios":"`Blueprint('', __name__)`, or passing `None`/any falsy value as the name — e.g. `Blueprint(some_var, __name__)` where `some_var` came back empty from config, an env var, or a string operation like `module.split('.')[-1]` on unexpected input.","commonSituations":"Programmatically generating blueprints in a plugin loader where the derived name is empty; swapping the argument order and passing an empty default; refactoring that moved the name into a variable that isn't populated yet at import time.","solutions":["Pass a non-empty literal name: `Blueprint('admin', __name__)`.","If the name is computed, validate it before constructing the blueprint and fail with context (which module produced the empty name).","Derive a fallback from the import name explicitly, e.g. `name or import_name.rsplit('.', 1)[-1]`, only if that's genuinely intended."],"exampleFix":"# before\nbp = Blueprint(\"\", __name__)\n\n# after\nbp = Blueprint(\"admin\", __name__)","handlingStrategy":"validation","validationCode":"name = name.strip()\nif not name:\n    raise ValueError('Blueprint name must be non-empty')\nbp = Blueprint(name, __name__)","typeGuard":"def is_valid_bp_name(name):\n    return isinstance(name, str) and bool(name.strip()) and '.' not in name","tryCatchPattern":null,"preventionTips":["Hardcode blueprint names as literals; don't derive them from possibly-empty config values","Validate names at config load time if blueprint names come from external input"],"tags":["flask","python","blueprints","validation","app-init"],"analyzedSha":"6a2f545bfd8ed31e19066a299296917e034aca58","analyzedAt":"2026-07-31T19:13:49.921Z","schemaVersion":2}