apache/beam · error · TypeError

Dependencies must be a list of strings, got {deps}

Error message

Dependencies must be a list of strings, got {deps}

What it means

extract_extra_dependencies reads config.dependencies for the inline Python/JsxLang transform family and validates it is a list of strings before passing them to the provider. A non-list value is rejected with a TypeError because the dependency injector expects an iterable of package specifiers.

Source

Thrown at sdks/python/apache_beam/yaml/yaml_transform.py:1073

      return spec['id']
    elif 'type' in spec:
      return spec['type']
    elif len(spec) == 1:
      return extract_name(next(iter(spec.values())))
    else:
      return ''
  elif isinstance(spec, str):
    return spec
  else:
    return ''


def extract_extra_dependencies(spec):
  deps = spec.get('config', {}).get('dependencies', [])
  if not deps:
    return [], spec
  if not isinstance(deps, list):
    raise TypeError(f'Dependencies must be a list of strings, got {deps}')
  return deps, dict(
      spec,
      config={k: v for k, v in spec['config'].items() if k != 'dependencies'})


def push_windowing_to_roots(spec):
  scope = LightweightScope(spec['transforms'])
  consumed_outputs_by_transform = collections.defaultdict(set)
  for transform in spec['transforms']:
    for _, input_ref in empty_if_explicitly_empty(transform['input']).items():
      try:
        transform_id, output = scope.get_transform_id_and_output_name(input_ref)
        consumed_outputs_by_transform[transform_id].add(output)
      except ValueError:
        # Could be an input or an ambiguity we'll raise later.
        pass

  for transform in spec['transforms']:

View on GitHub (pinned to 12126d8942)

Solutions

  1. Wrap the value in a YAML list: dependencies: [pandas, numpy].
  2. Ensure each element is a string package specifier.
  3. If no dependencies are needed, omit the key entirely (empty/missing is accepted).

Example fix

# before
config:
  dependencies: pandas
# after
config:
  dependencies:
    - pandas
Defensive patterns

Strategy: type-guard

Validate before calling

deps = spec.get('config', {}).get('dependencies', [])
if deps and not (isinstance(deps, list) and all(isinstance(d, str) for d in deps)):
    raise TypeError('dependencies must be a list of strings')

Type guard

def is_valid_deps(v):
    return not v or (isinstance(v, list) and all(isinstance(d, str) for d in v))

Try / catch

try:
    deps, spec = extract_extra_dependencies(spec)
except TypeError as e:
    if 'Dependencies must be a list of strings' in str(e):
        raw = spec['config']['dependencies']
        spec['config']['dependencies'] = [raw] if isinstance(raw, str) else list(raw)
        deps, spec = extract_extra_dependencies(spec)
    else:
        raise

Prevention

When it happens

Trigger: create_ptransform on a spec whose config contains dependencies set to a string, dict, or other non-list value, e.g. dependencies: pandas instead of dependencies: [pandas].

Common situations: YAML authors writing a single dependency as a bare string instead of a list; quoting mistakes turning a list into a string; copying config from docs that show comma-separated values.

Understand the failure class

Background: Type mismatch errors: IllegalArgumentException, TypeError and type guards across 150 open-source libraries — this error's family across 150 libraries.

Related errors


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