{"record":{"id":"4f5696a76c63dfa2","repo":"huggingface/transformers","slug":"per-component-config-dict-is-missing-entries-for","errorCode":null,"errorMessage":"Per-component `config` dict is missing entries for: {sorted(missing)}. Expected one entry per component: {sorted(components)}.","messagePattern":"Per-component `config` dict is missing entries for: (.+?)\\. Expected one entry per component: (.+?)\\.","errorType":"exception","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"src/transformers/exporters/base.py","lineNumber":187,"sourceCode":"                stays dynamic under a dynamic-shape export (`config.dynamic=True`).\n\n        Returns:\n            `dict[str, Any]`: `{component_name: backend_specific_artifact}` — same keys as\n            [`~exporters.utils.decompose_for_generation`]. Values are whatever\n            [`~HfExporter.export`] returns for the concrete backend (`ExportedProgram`,\n            `ONNXProgram`, `ExecutorchProgramManager`).\n        \"\"\"\n        components = decompose_for_generation(\n            model,\n            sample_inputs,\n            generation_config=generation_config,\n            multi_token_decode=multi_token_decode,\n        )\n\n        if isinstance(config, dict):\n            missing = set(components) - set(config)\n            if missing:\n                raise ValueError(\n                    f\"Per-component `config` dict is missing entries for: {sorted(missing)}. \"\n                    f\"Expected one entry per component: {sorted(components)}.\"\n                )\n            configs = config\n        else:\n            configs = dict.fromkeys(components, config)\n\n        exported: dict[str, object] = {}\n        for name, (submodel, subinputs) in components.items():\n            try:\n                exported[name] = self.export(submodel, subinputs, config=configs[name])\n            except Exception as e:\n                raise RuntimeError(\n                    f\"{type(self).__name__}.export failed on component '{name}' \"\n                    f\"(submodel={type(submodel).__name__}, input keys={list(subinputs)}).\"\n                ) from e\n\n        return exported","sourceCodeStart":169,"sourceCodeEnd":205,"githubUrl":"https://github.com/huggingface/transformers/blob/a597f974857b3d92939971296bc0deb93d33d780/src/transformers/exporters/base.py#L169-L205","documentation":"HfExporter.export_for_generation decomposes the model into named components (e.g. prefill/decode stages) via decompose_for_generation. When you pass config as a dict, it must contain exactly one entry per component name; this ValueError fires when components exist that have no key in your dict, and the message lists both the missing names and the full expected key set.","triggerScenarios":"Calling export_for_generation(model, inputs, config={\"prefill\": cfg}) when decomposition produces {\"prefill\", \"decode\"}; passing stage names that don't match (e.g. 'forward' vs 'prefill'); multi_token_decode=True yielding more components than your dict covers.","commonSituations":"Upgrading transformers where the component set for a model changed (new decode stages); enabling multi-token decode and reusing an old two-entry config dict; hand-writing per-stage configs from an outdated example.","solutions":["Add the missing keys listed in the message — the expected key set is printed verbatim.","If all stages should share one config, pass the config object itself (not a dict); it is broadcast to every component.","Log the components once (inspect the message of a deliberate run, or decompose_for_generation) and template your dict from that."],"exampleFix":"# before\nexporter.export_for_generation(model, inputs, config={\"prefill\": onnx_cfg})  # missing 'decode'\n\n# after (per-component)\nexporter.export_for_generation(model, inputs, config={\"prefill\": onnx_cfg, \"decode\": onnx_cfg})\n\n# after (shared config — simplest)\nexporter.export_for_generation(model, inputs, config=onnx_cfg)","handlingStrategy":"try-catch","validationCode":"# Components are model/config dependent; safest pre-check is a dry-run or sharing one config.\n# If you must pass a dict, share the same config object for all stages instead:\nexporter.export_for_generation(model, inputs, config=single_cfg)  # broadcast, cannot hit this error","typeGuard":null,"tryCatchPattern":"try:\n    out = exporter.export_for_generation(model, inputs, config=configs)\nexcept ValueError as e:\n    if \"missing entries for\" in str(e):\n        missing = ast.literal_eval(str(e).split(\"missing entries for:\")[1].split(\".\")[0])\n        configs.update({name: default_cfg for name in missing})\n        out = exporter.export_for_generation(model, inputs, config=configs)\n    else:\n        raise","preventionTips":["Default to passing a single config object (broadcast) unless stages truly differ","When passing per-stage dicts, regenerate them after upgrading transformers — component sets change","Pin the transformers version in export pipelines"],"tags":["export","generation","config","validation"],"backgroundTag":null,"analyzedSha":"a597f974857b3d92939971296bc0deb93d33d780","analyzedAt":"2026-08-14T18:24:08.354Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}