{"record":{"id":"91507a8d55f1b34d","repo":"apache/beam","slug":"missing-type-specification-in-identify-object-spec","errorCode":null,"errorMessage":"Missing type specification in {identify_object(spec)}","messagePattern":"Missing type specification in (.+?)","errorType":"exception","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"sdks/python/apache_beam/yaml/yaml_transform.py","lineNumber":1255,"sourceCode":"              'type': 'Flatten',\n              'name': '%s-Flatten[%s]' % (t.get('name', t['type']), key),\n              'input': {\n                  f'input{ix}': value\n                  for (ix, value) in enumerate(values)\n              },\n              '__line__': spec['__line__'],\n              '__uuid__': flatten_id,\n          })\n          replaced_inputs[key] = flatten_id\n      if replaced_inputs:\n        t = dict(t, input={**t['input'], **replaced_inputs})\n    new_transforms.append(t)\n  return dict(spec, transforms=new_transforms)\n\n\ndef ensure_transforms_have_types(spec):\n  if 'type' not in spec:\n    raise ValueError(f'Missing type specification in {identify_object(spec)}')\n  return spec\n\n\ndef ensure_errors_consumed(spec):\n  if spec['type'] == 'composite':\n    scope = LightweightScope(spec['transforms'])\n    to_handle = {}\n    consumed = set(\n        scope.get_transform_id_and_output_name(output)\n        for output in spec['output'].values())\n    for t in spec['transforms']:\n      config = t.get('config', t)\n      if 'error_handling' in config:\n        if 'output' not in config['error_handling']:\n          raise ValueError(\n              f'Missing output in error_handling of {identify_object(t)}')\n        to_handle[t['__uuid__'], config['error_handling']['output']] = t\n      for _, input in empty_if_explicitly_empty(t['input']).items():","sourceCodeStart":1237,"sourceCodeEnd":1273,"githubUrl":"https://github.com/apache/beam/blob/12126d8942aaf848030c478b4c6a28c6af861c66/sdks/python/apache_beam/yaml/yaml_transform.py#L1237-L1273","documentation":"ensure_transforms_have_types runs during pipeline preprocessing to guarantee every transform spec carries a 'type' field, which is required for provider lookup and expansion. A transform without a type cannot be instantiated, so preprocessing fails fast with this ValueError identifying the offending spec.","triggerScenarios":"Applying ensure_transforms_have_types to a spec dict lacking a top-level 'type' key — e.g. a transform entry in the YAML transforms list that only has name/config/input/output.","commonSituations":"Hand-edited YAML dropping the type line; programmatically constructed specs forgetting the type; copy-paste of a composite's child entry without its type; indented YAML attaching type under config instead of at the transform level.","solutions":["Add the required 'type' field to the transform spec (e.g. type: MapToFields).","Verify indentation so 'type' sits at the transform level, not nested under config.","If the transform should be generic, check that a provider exists for the intended type and set type explicitly."],"exampleFix":"# before\n- name: my_map\n  config:\n    language: python\n# after\n- type: MapToFields\n  name: my_map\n  config:\n    language: python","handlingStrategy":"validation","validationCode":"for t in spec.get('transforms', []):\n    if 'type' not in t:\n        raise ValueError(f\"transform {t.get('name')} is missing 'type'\")","typeGuard":"def has_type(t):\n    return isinstance(t, dict) and isinstance(t.get('type'), str) and bool(t['type'].strip())","tryCatchPattern":"try:\n    spec = ensure_transforms_have_types(spec)\nexcept ValueError as e:\n    if 'Missing type specification' in str(e):\n        raise SystemExit(f'Fix your YAML: {e}')\n    raise","preventionTips":["Ensure every entry in the transforms list has a top-level type key","Check YAML indentation so type is not nested under config","Lint YAML pipelines against the Beam YAML schema before running"],"tags":["python","apache-beam","yaml","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-20T03:17:13.778Z"}