{"record":{"id":"e6e5f55392cffdaf","repo":"pallets/flask","slug":"tag-key-is-already-registered","errorCode":null,"errorMessage":"Tag '{key}' is already registered.","messagePattern":"Tag '(.+?)' is already registered\\.","errorType":"exception","errorClass":"KeyError","httpStatus":null,"severity":"error","filePath":"src/flask/json/tag.py","lineNumber":280,"sourceCode":"        \"\"\"Register a new tag with this serializer.\n\n        :param tag_class: tag class to register. Will be instantiated with this\n            serializer instance.\n        :param force: overwrite an existing tag. If false (default), a\n            :exc:`KeyError` is raised.\n        :param index: index to insert the new tag in the tag order. Useful when\n            the new tag is a special case of an existing tag. If ``None``\n            (default), the tag is appended to the end of the order.\n\n        :raise KeyError: if the tag key is already registered and ``force`` is\n            not true.\n        \"\"\"\n        tag = tag_class(self)\n        key = tag.key\n\n        if key:\n            if not force and key in self.tags:\n                raise KeyError(f\"Tag '{key}' is already registered.\")\n\n            self.tags[key] = tag\n\n        if index is None:\n            self.order.append(tag)\n        else:\n            self.order.insert(index, tag)\n\n    def tag(self, value: t.Any) -> t.Any:\n        \"\"\"Convert a value to a tagged representation if necessary.\"\"\"\n        for tag in self.order:\n            if tag.check(value):\n                return tag.tag(value)\n\n        return value\n\n    def untag(self, value: dict[str, t.Any]) -> t.Any:\n        \"\"\"Convert a tagged representation back to the original type.\"\"\"","sourceCodeStart":262,"sourceCodeEnd":298,"githubUrl":"https://github.com/pallets/flask/blob/3596b1ab61cea85edb8970e83ff61daa073facf8/src/flask/json/tag.py#L262-L298","documentation":"TaggedJSONSerializer.register(tag_class) instantiates the tag, reads tag.key, and if key is truthy and already present in self.tags (and force=False), raises KeyError. This protects session/tag serialization from two tags claiming the same key, which would make encoded data ambiguous.","triggerScenarios":"Registering a custom JSONTag whose key collides with a built-in tag key (e.g. ' di', 'list', 'tuple') or with another custom tag already registered, without passing force=True. The dict self.tags maps key->tag and a duplicate would overwrite silently.","commonSituations":"Extending session serialization with a custom tag and accidentally reusing an existing key. Loading a Flask extension that registers a tag also registered by another extension. Upgrading Flask where a new built-in tag key now collides with your custom one.","solutions":["Choose a unique key for your custom JSONTag that does not collide with existing tags.","Pass force=True to register() if you intentionally want to override an existing tag.","Inspect app.session_interface.serializer.tags keys before registering to detect collisions."],"exampleFix":"# before\nclass MyTag(JSONTag):\n    key = 'list'   # collides with built-in\napp.session_interface.serializer.register(MyTag)  # KeyError\n\n# after\nclass MyTag(JSONTag):\n    key = 'mylist'\napp.session_interface.serializer.register(MyTag)\n# or override: register(MyTag, force=True)","handlingStrategy":"validation","validationCode":"def tag_key_available(serializer, key: str) -> bool:\n    return key not in serializer.tags","typeGuard":"def is_unique_tag_key(serializer, key: str) -> bool:\n    return key not in serializer.tags","tryCatchPattern":"try:\n    serializer.register(MyTag)\nexcept KeyError as e:\n    if 'already registered' in str(e):\n        serializer.register(MyTag, force=True)\n    else:\n        raise","preventionTips":["Inspect serializer.tags.keys() before registering a custom tag.","Use a distinctive key namespace for custom tags to avoid collisions."],"tags":["flask","session","json","serialization","configuration"],"backgroundTag":null,"analyzedSha":"3596b1ab61cea85edb8970e83ff61daa073facf8","analyzedAt":"2026-08-11T20:11:52.622Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}