{"record":{"id":"98dd53eab595da4a","repo":"apache/beam","slug":"cannot-specify-callable-with-path-and-name-for-typ-function","errorCode":null,"errorMessage":"Cannot specify 'callable' with 'path' and 'name' for {typ} function.","messagePattern":"Cannot specify 'callable' with 'path' and 'name' for (.+?) function\\.","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"sdks/python/apache_beam/yaml/yaml_ml.py","lineNumber":91,"sourceCode":"  def __init__(\n      self,\n      handler,\n      preprocess: Optional[dict[str, str]] = None,\n      postprocess: Optional[dict[str, str]] = None):\n    self._handler = handler\n    self._preprocess_fn = self.parse_processing_transform(\n        preprocess, 'preprocess') or self.default_preprocess_fn()\n    self._postprocess_fn = self.parse_processing_transform(\n        postprocess, 'postprocess') or self.default_postprocess_fn()\n\n  def inference_output_type(self):\n    return Any\n\n  @staticmethod\n  def parse_processing_transform(processing_transform, typ):\n    def _parse_config(callable=None, path=None, name=None):\n      if callable and (path or name):\n        raise ValueError(\n            f\"Cannot specify 'callable' with 'path' and 'name' for {typ} \"\n            f\"function.\")\n      if path and name:\n        return python_callable.PythonCallableWithSource.load_from_script(\n            FileSystems.open(path).read().decode(), name)\n      elif callable:\n        return python_callable.PythonCallableWithSource(callable)\n      else:\n        raise ValueError(\n            f\"Must specify one of 'callable' or 'path' and 'name' for {typ} \"\n            f\"function.\")\n\n    if processing_transform:\n      if isinstance(processing_transform, dict):\n        return _parse_config(**processing_transform)\n      else:\n        raise ValueError(\"Invalid model_handler specification.\")\n","sourceCodeStart":73,"sourceCodeEnd":109,"githubUrl":"https://github.com/apache/beam/blob/12126d8942aaf848030c478b4c6a28c6af861c66/sdks/python/apache_beam/yaml/yaml_ml.py#L73-L109","documentation":"Beam YAML ML's `parse_processing_transform` config parser (`_parse_config`, yaml_ml.py:91) accepts either an inline `callable` OR a `path`+`name` pair referencing a script, but not both. Specifying both is ambiguous, so a ValueError is raised.","triggerScenarios":"Calling parse_processing_transform / configuring a ML transform with a dict containing both a `callable` and a `path` (or `name`) key, e.g. {callable: my_fn, path: preprocess.py}.","commonSituations":"Copying a config template that had path/name and pasting an inline callable on top; merging two preprocess configs; leaving a leftover `path` key when switching to inline callables.","solutions":["Remove the `path`/`name` keys and keep only `callable` if you want an inline function.","Remove `callable` and keep `path` + `name` to load from a script file.","Validate the transform config dict before passing it so only one form is present."],"exampleFix":"# before\npreprocess: {callable: my_fn, path: preprocess.py, name: my_fn}\n# after\npreprocess: {path: preprocess.py, name: my_fn}","handlingStrategy":"validation","validationCode":"cfg = processing_transform if isinstance(processing_transform, dict) else {}\nif 'callable' in cfg and ('path' in cfg or 'name' in cfg):\n    raise ValueError('use either callable or path+name, not both')","typeGuard":"def has_conflicting_fn_config(cfg):\n    return 'callable' in cfg and bool(cfg.get('path') or cfg.get('name'))","tryCatchPattern":"try:\n    fn = parse_processing_transform(spec, typ)\nexcept ValueError as e:\n    raise YamlConfigError(f'preprocess config invalid: {e}') from e","preventionTips":["Choose one form: inline callable OR script path+name, never both.","When editing configs, remove the alternative form's keys entirely.","Validate preprocess blocks with a schema check before submitting the pipeline."],"tags":["python","apache-beam","yaml-ml","config-conflict"],"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"}