{"record":{"id":"fd52d12afb660a6d","repo":"huggingface/transformers","slug":"weightconverter-requires-at-least-one-operation","errorCode":null,"errorMessage":"WeightConverter requires at least one operation.","messagePattern":"WeightConverter requires at least one operation\\.","errorType":"exception","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"src/transformers/core_model_loading.py","lineNumber":1154,"sourceCode":"\n\nclass WeightConverter(WeightTransform):\n    __slots__ = (\"operations\",)\n\n    def __init__(\n        self, source_patterns: str | list[str], target_patterns: str | list[str], operations: list[ConversionOps]\n    ):\n        super().__init__(source_patterns, target_patterns)\n        self.operations: list[ConversionOps] = operations\n\n        if bool(len(self.source_patterns) - 1) + bool(len(self.target_patterns) - 1) >= 2:\n            # We allow many-to-many only if we use an internal operation that can handle it\n            if not any(isinstance(op, _INTERNAL_MANY_TO_MANY_CONVERSIONS) for op in self.operations):\n                raise ValueError(\n                    f\"source keys={self.source_patterns}, target_patterns={self.target_patterns} but you can only have one to many, one to one or many to one.\"\n                )\n        if not self.operations:\n            raise ValueError(\"WeightConverter requires at least one operation.\")\n\n    def convert(\n        self,\n        layer_name: str,\n        model=None,\n        config=None,\n        hf_quantizer=None,\n        loading_info: LoadStateDictInfo | None = None,\n    ):\n        # Collect the tensors here - we use a new dictionary to avoid keeping them in memory in the internal\n        # attribute during the whole process\n        collected_tensors = self.materialize_tensors()\n\n        for op in self.operations:\n            with log_conversion_errors(layer_name, loading_info, (len(collected_tensors), layer_name), op):\n                collected_tensors = op.convert(\n                    collected_tensors,\n                    source_patterns=self.source_patterns,","sourceCodeStart":1136,"sourceCodeEnd":1172,"githubUrl":"https://github.com/huggingface/transformers/blob/a597f974857b3d92939971296bc0deb93d33d780/src/transformers/core_model_loading.py#L1136-L1172","documentation":"Raised by WeightConverter.__init__ (core_model_loading.py:1154). A WeightConverter is defined by its list of tensor operations (the actual conversion math); an empty operations list means there is nothing to convert, which almost always indicates the caller passed an uninitialized/empty list or forgot the argument. The constructor validates this after the cardinality check and refuses to build an operation-less converter.","triggerScenarios":"WeightConverter(source_patterns=[...], target_patterns=[...], operations=[]) — e.g. operations were built conditionally and the condition never fired, leaving an empty list; or a refactor left the default empty list in place.","commonSituations":"Programmatic recipe builders that accumulate ops in a loop which never executes (empty config section, wrong filter), or copy-paste where the operations argument was dropped. If you only need a rename, use WeightTransform (no operations) instead of WeightConverter.","solutions":["If you only need key renaming with no tensor math, use WeightTransform/GroupWeightRename/PrefixChange instead of WeightConverter.","If tensor conversion is intended, pass at least one op (e.g. Identity-like op or the real conversion) in operations.","In programmatic builders, assert the ops list is non-empty before constructing to surface the upstream logic error."],"exampleFix":"# before\nWeightConverter(source_patterns=[r'blk.*'], target_patterns=[r'layers.*'], operations=ops)  # ops == []\n\n# after: pure rename -> WeightTransform\nWeightTransform(source_patterns=[r'blk.*'], target_patterns=[r'layers.*'])","handlingStrategy":"validation","validationCode":"assert isinstance(operations, list) and len(operations) > 0, (\n    'WeightConverter needs >=1 operation; use WeightTransform for pure renames'\n)","typeGuard":"def has_operations(operations) -> bool:\n    return bool(operations)","tryCatchPattern":null,"preventionTips":["Use WeightTransform (or GroupWeightRename/PrefixChange) for pure key renames — no operations needed.","Assert ops lists are non-empty where they are built dynamically (loops/filters).","Lint recipes for WeightConverter instantiations with literal empty operations=[]."],"tags":["weight-conversion","validation","programmer-error"],"backgroundTag":null,"analyzedSha":"a597f974857b3d92939971296bc0deb93d33d780","analyzedAt":"2026-08-14T18:24:08.354Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}