{"record":{"id":"6fa7dfac73b08b82","repo":"huggingface/transformers","slug":"exporter-must-extend-hfexporter","errorCode":null,"errorMessage":"Exporter must extend HfExporter","messagePattern":"Exporter must extend HfExporter","errorType":"exception","errorClass":"TypeError","httpStatus":null,"severity":"error","filePath":"src/transformers/exporters/auto.py","lineNumber":165,"sourceCode":"                f\"Export format {name!r} has a registered exporter but no config class. \"\n                f\"Register one via ``@register_export_config({name!r})``. Skipping.\"\n            )\n            return False\n        if not has_exporter:\n            logger.warning(\n                f\"Export format {name!r} has a registered config class but no exporter. \"\n                f\"Register one via ``@register_exporter({name!r})``. Skipping.\"\n            )\n            return False\n        return True\n\n\ndef register_exporter(name: str):\n    def register_exporter_fn(cls):\n        if name in AUTO_EXPORTER_MAPPING:\n            logger.warning(f\"Exporter '{name}' is already registered and will be overwritten.\")\n        if not issubclass(cls, HfExporter):\n            raise TypeError(\"Exporter must extend HfExporter\")\n        AUTO_EXPORTER_MAPPING[name] = cls\n        return cls\n\n    return register_exporter_fn\n\n\ndef register_export_config(name: str):\n    def register_export_config_fn(cls):\n        if name in AUTO_EXPORT_CONFIG_MAPPING:\n            logger.warning(f\"Export config '{name}' is already registered and will be overwritten.\")\n        if not issubclass(cls, ExportConfigMixin):\n            raise TypeError(\"Export config must extend ExportConfigMixin\")\n        AUTO_EXPORT_CONFIG_MAPPING[name] = cls\n        return cls\n\n    return register_export_config_fn\n\n","sourceCodeStart":147,"sourceCodeEnd":183,"githubUrl":"https://github.com/huggingface/transformers/blob/a597f974857b3d92939971296bc0deb93d33d780/src/transformers/exporters/auto.py#L147-L183","documentation":"The @register_exporter(name) decorator raises TypeError when the decorated class is not a subclass of HfExporter. The registry stores factory classes that must implement the abstract exporter interface (dependency checks, export, export_for_generation), so anything else would break AutoHfExporter.from_config at instantiation time.","triggerScenarios":"Applying @register_exporter(\"mybackend\") to a plain class, a function-style wrapper, or a class inheriting only from object; multiple inheritance where HfExporter is not in the MRO.","commonSituations":"Writing a custom backend (TensorRT, TFLite, CoreML) and wiring it into the auto-factory; refactoring an existing exporter so it no longer inherits HfExporter.","solutions":["Make the decorated class inherit from HfExporter: class MyExporter(HfExporter): ... and implement export().","If you only want a config (no custom exporter), use @register_export_config instead.","Verify with issubclass(MyExporter, HfExporter) before decorating."],"exampleFix":"# before\n@register_exporter(\"trt\")\nclass TrtExporter:  # TypeError\n    ...\n\n# after\nfrom transformers.exporters.base import HfExporter\n\n@register_exporter(\"trt\")\nclass TrtExporter(HfExporter):\n    def export(self, model, sample_inputs, config): ...","handlingStrategy":"type-guard","validationCode":"from transformers.exporters.base import HfExporter\n\nassert issubclass(MyExporter, HfExporter), \"custom exporters must subclass HfExporter\"\nregister_exporter(\"mybackend\")(MyExporter)","typeGuard":"def is_valid_exporter(cls) -> bool:\n    from transformers.exporters.base import HfExporter\n    return isinstance(cls, type) and issubclass(cls, HfExporter)","tryCatchPattern":null,"preventionTips":["Import HfExporter in the same module where you define custom exporters so the inheritance is visible","Add a unit test asserting your plugin registers cleanly (decorator raises TypeError at import time otherwise)"],"tags":["export","registry","plugin","type-error"],"backgroundTag":null,"analyzedSha":"a597f974857b3d92939971296bc0deb93d33d780","analyzedAt":"2026-08-14T18:24:08.354Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}