{"record":{"id":"1fa7ddd71f4de749","repo":"apache/beam","slug":"transform-name-cannot-specify-both-expression-and-callable","errorCode":null,"errorMessage":"{transform_name} cannot specify both \"expression\" and \"callable\"","messagePattern":"(.+?) cannot specify both \"expression\" and \"callable\"","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"sdks/python/apache_beam/yaml/yaml_mapping.py","lineNumber":171,"sourceCode":"  if base_type == 'MapToFields':\n    for field, value in list(config.get('fields', {}).items()):\n      validate_generic_expression(value, input_fields, True, field)\n\n  elif base_type in _str_expression_fields:\n    param = _str_expression_fields[base_type]\n    validate_generic_expression(\n        config.get(param), input_fields, base_type == 'Filter', param)\n\n\ndef _check_mapping_arguments(\n    transform_name, expression=None, callable=None, name=None, path=None):\n  # Argument checking\n  if not expression and not callable and not path and not name:\n    raise ValueError(\n        f'{transform_name} must specify either \"expression\", \"callable\", '\n        f'or both \"path\" and \"name\"')\n  if expression and callable:\n    raise ValueError(\n        f'{transform_name} cannot specify both \"expression\" and \"callable\"')\n  if (expression or callable) and (path or name):\n    raise ValueError(\n        f'{transform_name} cannot specify \"expression\" or \"callable\" with '\n        f'\"path\" or \"name\"')\n  if path and not name:\n    raise ValueError(f'{transform_name} cannot specify \"path\" without \"name\"')\n  if name and not path:\n    raise ValueError(f'{transform_name} cannot specify \"name\" without \"path\"')\n\n\n_THREAD_LOCAL_JS_CACHE = threading.local()\n\n\nclass _JsFunctionWrapper:\n  def __init__(self, source_code, entrypoint_name):\n    self.source_code = source_code\n    self.entrypoint_name = entrypoint_name","sourceCodeStart":153,"sourceCodeEnd":189,"githubUrl":"https://github.com/apache/beam/blob/12126d8942aaf848030c478b4c6a28c6af861c66/sdks/python/apache_beam/yaml/yaml_mapping.py#L153-L189","documentation":"_check_mapping_arguments enforces mutually exclusive definition styles: an inline expression and a callable cannot both be given. This ValueError fires when both 'expression' and 'callable' are truthy in the transform configuration.","triggerScenarios":"Configuring a mapping transform with both an `expression` string and a `callable` option simultaneously, through _as_callable.","commonSituations":"Merging two transform configs; switching from inline expression to a callable and forgetting to delete the expression; YAML anchors accidentally merging both fields.","solutions":["Remove the `expression` if you intend to use a callable.","Remove the `callable` if you intend to use an inline expression.","Check YAML anchors/overrides that may merge both keys unintentionally.","Pick one definition style per field."],"exampleFix":"# before\nconfig:\n  expression: \"x + 1\"\n  callable: my_func\n# after\nconfig:\n  expression: \"x + 1\"","handlingStrategy":"validation","validationCode":"assert not (config.get('expression') and config.get('callable')), 'choose expression OR callable'","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Keep one definition style per field","Beware YAML anchors merging keys","Review diffs when switching definition styles"],"tags":["yaml","beam-yaml","conflicting-options"],"backgroundTag":"mutually-exclusive-options","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"}