{"record":{"id":"7902c81dd5d31f01","repo":"apache/beam","slug":"missing-language-for-identify-object-spec","errorCode":null,"errorMessage":"Missing language for {identify_object(spec)}","messagePattern":"Missing language for (.+?)","errorType":"exception","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"sdks/python/apache_beam/yaml/yaml_transform.py","lineNumber":1346,"sourceCode":"  def ensure_transforms_have_providers(spec):\n    if known_transforms:\n      if spec['type'] not in known_transforms:\n        raise ValueError(\n            'Unknown type or missing provider '\n            f'for type {spec[\"type\"]} for {identify_object(spec)}')\n    return spec\n\n  def preprocess_languages(spec):\n    if spec['type'] in ('AssignTimestamps',\n                        'Combine',\n                        'Filter',\n                        'MapToFields',\n                        'Partition'):\n      language = spec.get('config', {}).get('language', 'generic')\n      new_type = spec['type'] + '-' + language\n      if known_transforms and new_type not in known_transforms:\n        if language == 'generic':\n          raise ValueError(f'Missing language for {identify_object(spec)}')\n        else:\n          raise ValueError(\n              f'Unknown language {language} for {identify_object(spec)}')\n      return dict(spec, type=new_type, name=spec.get('name', spec['type']))\n    else:\n      return spec\n\n  def validate_transform_references(spec):\n    name = spec.get('name', '')\n    transform_type = spec.get('type')\n    inputs = spec.get('input').get('input', [])\n\n    if not is_empty(inputs):\n      input_values = [inputs] if isinstance(inputs, str) else inputs\n      for input_value in input_values:\n        if input_value in (name, transform_type):\n          raise ValueError(\n              f\"Circular reference detected: Transform {name} \"","sourceCodeStart":1328,"sourceCodeEnd":1364,"githubUrl":"https://github.com/apache/beam/blob/12126d8942aaf848030c478b4c6a28c6af861c66/sdks/python/apache_beam/yaml/yaml_transform.py#L1328-L1364","documentation":"Several generic-language transforms (e.g. AssignTimestamps, MapToFields, Partition) get rewritten by preprocess_languages to type-<language>. If no explicit language was configured (defaulting to 'generic') and no provider exists for the '<type>-generic' variant, the pipeline cannot resolve the transform, so this ValueError is raised telling the author to specify a language.","triggerScenarios":"preprocess_languages on a spec for a language-sensitive transform where spec.config has no 'language' key (so language='generic'), known_transforms is non-empty, and '<type>-generic' is not in known_transforms.","commonSituations":"Omitting config.language when the environment only offers a specific-language provider (e.g. only python or only java registered); copy-pasting specs across pipelines with different provider sets; assuming a default language that the runner does not ship.","solutions":["Add an explicit language in config, e.g. config: {language: python}.","Register a provider for the generic variant of the transform.","Choose a concrete-language transform type instead of the generic one."],"exampleFix":"# before\n- type: MapToFields\n  config:\n    fields: {x: expr}\n# after\n- type: MapToFields\n  config:\n    language: python\n    fields: {x: expr}","handlingStrategy":"validation","validationCode":"LANG_SENSITIVE = ('AssignTimestamps', 'MapToFields', 'Partition')\nfor t in spec.get('transforms', []):\n    if t.get('type') in LANG_SENSITIVE and 'language' not in t.get('config', {}):\n        print(f\"warning: {t.get('name')} has no explicit language; set config.language\")","typeGuard":"def has_language(t):\n    return isinstance(t.get('config', {}).get('language'), str)","tryCatchPattern":"try:\n    spec = expand_pipeline(spec, providers=providers)\nexcept ValueError as e:\n    if 'Missing language for' in str(e):\n        raise SystemExit(f\"{e} — add config.language (e.g. python)\")\n    raise","preventionTips":["Always set config.language explicitly for MapToFields/AssignTimestamps/Partition","Match language to the providers actually registered in your environment","Document the required language in pipeline templates"],"tags":["python","apache-beam","yaml","language","provider"],"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"}