apache/beam · error · ValueError

"Cannot specify 'callable' with 'path' and 'name' for functi

Error message

"Cannot specify 'callable' with 'path' and 'name' for function."

What it means

maybe_make_specifiable converts YAML values into callable/Specifiable objects. A value containing 'callable' specifies an inline Python callable; 'path'+'name' specifies loading from a script. These two forms are mutually exclusive, so specifying 'callable' together with 'path' or 'name' raises a ValueError.

Source

Thrown at sdks/python/apache_beam/yaml/yaml_specifiable.py:34

#

from apache_beam.io.filesystems import FileSystems
from apache_beam.ml.anomaly.specifiable import Spec
from apache_beam.ml.anomaly.transforms import AnomalyDetection
from apache_beam.ml.anomaly.transforms import Specifiable
from apache_beam.utils import python_callable
from apache_beam.yaml.yaml_provider import InlineProvider


def maybe_make_specifiable(v):
  if isinstance(v, dict):
    if "type" in v and "config" in v:
      return Specifiable.from_spec(
          Spec(type=v["type"], config=maybe_make_specifiable(v["config"])))

    if "callable" in v:
      if "path" in v or "name" in v:
        raise ValueError(
            "Cannot specify 'callable' with 'path' and 'name' for function.")
      else:
        return python_callable.PythonCallableWithSource(v["callable"])

    if "path" in v and "name" in v:
      return python_callable.PythonCallableWithSource.load_from_script(
          FileSystems.open(v["path"]).read().decode(), v["name"])

    ret = {k: maybe_make_specifiable(v[k]) for k in v}
    return ret
  else:
    return v


class SpecProvider(InlineProvider):
  def create_transform(self, type, args, yaml_create_transform):
    return self._transform_factories[type](
        **{

View on GitHub (pinned to 12126d8942)

Solutions

  1. Remove 'path' and 'name' keys when providing an inline 'callable'.
  2. Remove 'callable' and keep only 'path' and 'name' to load from a script.
  3. Split the config so exactly one specification form remains.

Example fix

# before
fn:
  callable: 'lambda x: x + 1'
  path: my_funcs.py
  name: increment

# after
fn:
  callable: 'lambda x: x + 1'
Defensive patterns

Strategy: validation

Validate before calling

if isinstance(v, dict) and 'callable' in v and ('path' in v or 'name' in v):
    raise ValueError('Use either callable or path+name, not both')

Type guard

def is_valid_callable_spec(v: dict) -> bool:
    has_callable = 'callable' in v
    has_script = 'path' in v and 'name' in v
    return has_callable != has_script

Try / catch

try:
    fn = maybe_make_specifiable(v)
except ValueError as e:
    logging.error('Specifiable config conflict: %s', e)
    raise

Prevention

When it happens

Trigger: Passing a dict like {'callable': 'lambda x: x', 'path': 'my_mod.py'} or {'callable': ..., 'name': 'my_func'} to a specifiable field (e.g. a map's fn or a filter's language expression argument).

Common situations: Users paste an inline callable into a config that was previously script-based, or leave stale 'path'/'name' keys behind when inlining the function.

Related errors


AI-assisted analysis of apache/beam@12126d8942 (2026-09-13). Data as JSON: /api/errors/478e21ca8920bbd4. Report an issue: GitHub.