{"record":{"id":"fa8e5cc372b8809c","repo":"apache/beam","slug":"missing-type-parameter-for-transform-at-identify-object-spec","errorCode":null,"errorMessage":"Missing type parameter for transform at {identify_object(spec)}","messagePattern":"Missing type parameter for transform at (.+?)","errorType":"exception","errorClass":"TypeError","httpStatus":null,"severity":"error","filePath":"sdks/python/apache_beam/yaml/yaml_transform.py","lineNumber":478,"sourceCode":"      strictness += 1\n    elif ('ExternalTransform' not in ptransform.label and\n          not ptransform.label.startswith('_')):\n      # The label may have interesting information.\n      name = ptransform.label\n    else:\n      name = spec['type']\n    if name in self._seen_names:\n      if strictness >= 2:\n        raise ValueError(f'Duplicate name at {identify_object(spec)}: {name}')\n      else:\n        name = f'{name}@{SafeLineLoader.get_line(spec)}'\n    self._seen_names.add(name)\n    return name\n\n\ndef expand_transform(spec, scope):\n  if 'type' not in spec:\n    raise TypeError(\n        f'Missing type parameter for transform at {identify_object(spec)}')\n  type = spec['type']\n  if type == 'composite':\n    return expand_composite_transform(spec, scope)\n  else:\n    return expand_leaf_transform(spec, scope)\n\n\ndef expand_leaf_transform(spec, scope):\n  spec = spec.copy()\n\n  # Check for optional output_schema to verify on.\n  # The idea is to pass this output_schema config to the ValidateWithSchema\n  # transform.\n  output_schema_spec = {}\n  if 'output_schema' in spec.get('config', {}):\n    output_schema_spec = spec.get('config').pop('output_schema')\n","sourceCodeStart":460,"sourceCodeEnd":496,"githubUrl":"https://github.com/apache/beam/blob/12126d8942aaf848030c478b4c6a28c6af861c66/sdks/python/apache_beam/yaml/yaml_transform.py#L460-L496","documentation":"Apache Beam YAML raises this TypeError from expand_transform when a transform spec dict has no 'type' field. Every node in a Beam YAML pipeline must declare its transform type (e.g. 'ReadFromText', 'MapToFields', 'composite', 'chain'). Without it the framework cannot decide which expansion path (composite vs leaf) to take.","triggerScenarios":"Calling expand_transform(spec, scope) — directly or via expand/compute_outputs — with a spec dict that omits the 'type' key, e.g. {'name': 'MyTransform', 'inputs': [...]} or a YAML stanza where 'type:' was mis-indented so it parsed into a sibling mapping instead of the transform.","commonSituations":"Hand-written YAML pipelines with a missing or misspelled 'type:' key (e.g. 'Type:' with capital T); programmatically constructed specs in tests or tools forgetting 'type'; YAML indentation errors that detach 'type' from its transform block.","solutions":["Add a 'type' key to the transform spec naming a valid Beam YAML transform type.","Check YAML indentation so 'type:' is nested inside the transform mapping, not a sibling.","Verify spelling/casing: the key must be exactly 'type' (lowercase).","If generating specs in code, validate each spec dict contains 'type' before calling expand_transform."],"exampleFix":"# before\n- name: ReadInput\n  input: {}\n  config:\n    path: input.json\n# after\n- name: ReadInput\n  type: ReadFromJson\n  config:\n    path: input.json","handlingStrategy":"validation","validationCode":"def check_spec(spec):\n    if not isinstance(spec, dict) or 'type' not in spec:\n        raise ValueError(f\"Transform spec missing required 'type' key: {spec}\")","typeGuard":"def has_type(spec) -> bool:\n    return isinstance(spec, dict) and isinstance(spec.get('type'), str)","tryCatchPattern":"try:\n    expand_transform(spec, scope)\nexcept TypeError as e:\n    if 'Missing type parameter' in str(e):\n        print(f\"Fix YAML: {e}\")\n    else:\n        raise","preventionTips":["Always include 'type:' as the first key in each YAML transform block.","Run `python -m apache_beam.yaml.main --validate` or schema-validate specs in CI.","Watch for YAML indentation that detaches 'type' from its mapping."],"tags":["python","apache-beam","yaml","config"],"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"}