{"record":{"id":"37292b5fd9871616","repo":"apache/beam","slug":"missing-config-in-ml-transform-spec-spec","errorCode":null,"errorMessage":"Missing config in ML transform spec {spec}","messagePattern":"Missing config in ML transform spec (.+?)","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"sdks/python/apache_beam/yaml/yaml_ml.py","lineNumber":593,"sourceCode":"      pcoll | RunInference(\n          model_handler=KeyedModelHandler(\n              model_handler_provider.underlying_handler()).with_preprocess_fn(\n                  model_handler_provider._preprocess_fn_internal()).\n          with_postprocess_fn(\n              model_handler_provider._postprocess_fn_internal()),\n          inference_args=inference_args)\n      | beam.Map(\n          lambda row: beam.Row(\n              **{\n                  **row[0]._asdict(), str(inference_tag): row[1]\n              })).with_output_types(schema))\n\n\ndef _config_to_obj(spec):\n  if 'type' not in spec:\n    raise ValueError(f\"Missing type in ML transform spec {spec}\")\n  if 'config' not in spec:\n    raise ValueError(f\"Missing config in ML transform spec {spec}\")\n  constructor = _transform_constructors.get(spec['type'])\n  if constructor is None:\n    raise ValueError(\"Unknown ML transform type: %r\" % spec['type'])\n  return constructor(**spec['config'])\n\n\n@beam.ptransform.ptransform_fn\ndef ml_transform(\n    pcoll,\n    write_artifact_location: Optional[str] = None,\n    read_artifact_location: Optional[str] = None,\n    transforms: Optional[list[Any]] = None):\n  if MLTransform is None:\n    raise ValueError(\n        'No MLTransform found. Please install tensorflow-transform or '\n        'sentence-transformers to use this transform.')\n  options.YamlOptions.check_enabled(pcoll.pipeline, 'ML')\n  result_ml_transform = MLTransform(","sourceCodeStart":575,"sourceCodeEnd":611,"githubUrl":"https://github.com/apache/beam/blob/12126d8942aaf848030c478b4c6a28c6af861c66/sdks/python/apache_beam/yaml/yaml_ml.py#L575-L611","documentation":"_config_to_obj found a 'type' in the ML transform spec but no 'config' mapping; providers are constructed from their configuration dict, so its absence leaves nothing to instantiate the transform with.","triggerScenarios":"An ML transform spec like {'type': 'RunInference'} with no 'config' key; config misspelled or misplaced due to YAML indentation.","commonSituations":"Transforms whose options were accidentally placed as siblings of type/config; specs copied without their config block; empty-config transforms where users omit the key instead of passing config: {}.","solutions":["Add a 'config' key with the transform options (use {} for defaults)","Fix YAML indentation so options are nested under config","Check key spelling: it must be exactly 'config'"],"exampleFix":"# before\n- name: inference\n  type: RunInference\n# after\n- name: inference\n  type: RunInference\n  config:\n    model_handler:\n      type: VertexAI\n      config: {endpoint_id: '123', project: 'my-project'}","handlingStrategy":"validation","validationCode":"def check_spec_config(spec):\n    if 'config' not in spec:\n        raise ValueError(f'ML transform spec needs config: {spec}')","typeGuard":"def has_config(spec):\n    return isinstance(spec, dict) and isinstance(spec.get('config'), dict)","tryCatchPattern":null,"preventionTips":["Always provide a 'config' key, even if empty ({})","Keep transform options nested under config","Validate specs before constructing transforms"],"tags":["python","apache-beam","yaml","ml","validation"],"backgroundTag":"missing-required-config-field","analyzedSha":"12126d8942aaf848030c478b4c6a28c6af861c66","analyzedAt":"2026-09-13T01:50:10.254Z","contentChangedAt":"2026-09-13T01:50:10.254Z","schemaVersion":2},"datasetVersion":"2026-09-14T16:17:12.679Z"}