{"record":{"id":"b8a1c3087f2bf402","repo":"huggingface/transformers","slug":"you-must-provide-only-one-of-prefix-to-add-and","errorCode":null,"errorMessage":"You must provide only one of `prefix_to_add` and `prefix_to_remove`","messagePattern":"You must provide only one of `prefix_to_add` and `prefix_to_remove`","errorType":"exception","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"src/transformers/core_model_loading.py","lineNumber":1100,"sourceCode":"\n\nclass PrefixChange(WeightRenaming):\n    \"\"\"\n    Special case of WeightRenaming, used to simplify adding/removing full parts of a weight name. The regexes\n    that are needed for such operations are complex, so this is a much easier API for such cases.\n    \"\"\"\n\n    __slots__ = (\n        \"prefix_to_add\",\n        \"prefix_to_remove\",\n        \"model_prefix\",\n    )\n\n    def __init__(\n        self, prefix_to_add: str | None = None, prefix_to_remove: str | None = None, model_prefix: str | None = None\n    ):\n        if (prefix_to_add is None) ^ (prefix_to_remove is not None):\n            raise ValueError(\"You must provide only one of `prefix_to_add` and `prefix_to_remove`\")\n\n        self.prefix_to_add = prefix_to_add\n        self.prefix_to_remove = prefix_to_remove\n        self.model_prefix = \"\" if model_prefix is None else model_prefix\n        prefix = rf\"{self.model_prefix}\\.\" if self.model_prefix != \"\" else \"\"\n\n        if prefix_to_add is not None:\n            super().__init__(\n                # We use a lookbehind to avoid adding the prefix if we detect that it's already present\n                source_patterns=rf\"^{prefix}(?:(?!{prefix_to_add}\\.))(.+)$\",\n                target_patterns=rf\"{prefix}{prefix_to_add}\\.\\1\",\n            )\n        else:\n            super().__init__(source_patterns=rf\"^{prefix}{prefix_to_remove}\\.(.+)$\", target_patterns=rf\"{prefix}\\1\")\n\n    def reverse_transform(self) -> WeightTransform:\n        \"\"\"Reverse the current `WeightTransform` instance, to be able to save with the opposite weight transformations.\"\"\"\n        # TODO: check this and relax when quantizer have `reverse_op`","sourceCodeStart":1082,"sourceCodeEnd":1118,"githubUrl":"https://github.com/huggingface/transformers/blob/a597f974857b3d92939971296bc0deb93d33d780/src/transformers/core_model_loading.py#L1082-L1118","documentation":"Raised by PrefixChange.__init__ (core_model_loading.py:1100). This transform either adds a key prefix or removes one — exactly one action per instance. The XOR check `(prefix_to_add is None) ^ (prefix_to_remove is not None)` raises when BOTH arguments are None (nothing to do, almost certainly a caller bug) or when BOTH are provided (ambiguous direction).","triggerScenarios":"PrefixChange() with no arguments, or PrefixChange(prefix_to_add='visual', prefix_to_remove='visual'). Also triggered by code that passes both because it copies defaults.","commonSituations":"Programmatically building prefix transforms and passing the same variable to both parameters, or forgetting to pass either. Common in scripts that migrate key prefixes between checkpoint formats (e.g. adding/removing 'model.' or 'vision_tower.').","solutions":["Pass exactly one of prefix_to_add or prefix_to_remove.","Use keyword arguments to make the intent explicit.","If your code computes prefixes conditionally, assert that exactly one is non-None before constructing."],"exampleFix":"# before\nPrefixChange(prefix_to_add='visual', prefix_to_remove='visual')  # raises\n\n# after\nPrefixChange(prefix_to_add='visual')\n# or\nPrefixChange(prefix_to_remove='visual')","handlingStrategy":"validation","validationCode":"assert (prefix_to_add is None) != (prefix_to_remove is None), (\n    'provide exactly one of prefix_to_add / prefix_to_remove'\n)","typeGuard":"def is_exactly_one_set(*vals) -> bool:\n    return sum(v is not None for v in vals) == 1","tryCatchPattern":null,"preventionTips":["Always call PrefixChange with a single keyword argument (prefix_to_add=... XOR prefix_to_remove=...).","When prefixes come from config, assert exactly one is non-None before constructing.","Remember model_prefix is optional and orthogonal — it never replaces the add/remove pair choice."],"tags":["weight-conversion","rename","prefix","validation","programmer-error"],"backgroundTag":null,"analyzedSha":"a597f974857b3d92939971296bc0deb93d33d780","analyzedAt":"2026-08-14T18:24:08.354Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}