{"record":{"id":"4ff7fa1ec9e63c8e","repo":"apache/beam","slug":"dependencies-must-be-a-list-of-strings-got-deps","errorCode":null,"errorMessage":"Dependencies must be a list of strings, got {deps}","messagePattern":"Dependencies must be a list of strings, got (.+?)","errorType":"exception","errorClass":"TypeError","httpStatus":null,"severity":"error","filePath":"sdks/python/apache_beam/yaml/yaml_transform.py","lineNumber":1073,"sourceCode":"      return spec['id']\n    elif 'type' in spec:\n      return spec['type']\n    elif len(spec) == 1:\n      return extract_name(next(iter(spec.values())))\n    else:\n      return ''\n  elif isinstance(spec, str):\n    return spec\n  else:\n    return ''\n\n\ndef extract_extra_dependencies(spec):\n  deps = spec.get('config', {}).get('dependencies', [])\n  if not deps:\n    return [], spec\n  if not isinstance(deps, list):\n    raise TypeError(f'Dependencies must be a list of strings, got {deps}')\n  return deps, dict(\n      spec,\n      config={k: v for k, v in spec['config'].items() if k != 'dependencies'})\n\n\ndef push_windowing_to_roots(spec):\n  scope = LightweightScope(spec['transforms'])\n  consumed_outputs_by_transform = collections.defaultdict(set)\n  for transform in spec['transforms']:\n    for _, input_ref in empty_if_explicitly_empty(transform['input']).items():\n      try:\n        transform_id, output = scope.get_transform_id_and_output_name(input_ref)\n        consumed_outputs_by_transform[transform_id].add(output)\n      except ValueError:\n        # Could be an input or an ambiguity we'll raise later.\n        pass\n\n  for transform in spec['transforms']:","sourceCodeStart":1055,"sourceCodeEnd":1091,"githubUrl":"https://github.com/apache/beam/blob/12126d8942aaf848030c478b4c6a28c6af861c66/sdks/python/apache_beam/yaml/yaml_transform.py#L1055-L1091","documentation":"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.","triggerScenarios":"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].","commonSituations":"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.","solutions":["Wrap the value in a YAML list: dependencies: [pandas, numpy].","Ensure each element is a string package specifier.","If no dependencies are needed, omit the key entirely (empty/missing is accepted)."],"exampleFix":"# before\nconfig:\n  dependencies: pandas\n# after\nconfig:\n  dependencies:\n    - pandas","handlingStrategy":"type-guard","validationCode":"deps = spec.get('config', {}).get('dependencies', [])\nif deps and not (isinstance(deps, list) and all(isinstance(d, str) for d in deps)):\n    raise TypeError('dependencies must be a list of strings')","typeGuard":"def is_valid_deps(v):\n    return not v or (isinstance(v, list) and all(isinstance(d, str) for d in v))","tryCatchPattern":"try:\n    deps, spec = extract_extra_dependencies(spec)\nexcept TypeError as e:\n    if 'Dependencies must be a list of strings' in str(e):\n        raw = spec['config']['dependencies']\n        spec['config']['dependencies'] = [raw] if isinstance(raw, str) else list(raw)\n        deps, spec = extract_extra_dependencies(spec)\n    else:\n        raise","preventionTips":["Always express dependencies as YAML lists, even for one item","Validate the spec against the transform schema before expansion","Avoid comma-separated dependency strings"],"tags":["python","apache-beam","yaml","typeerror","dependencies"],"backgroundTag":"type-mismatch","analyzedSha":"12126d8942aaf848030c478b4c6a28c6af861c66","analyzedAt":"2026-09-13T01:50:10.254Z","contentChangedAt":"2026-09-13T01:50:10.254Z","schemaVersion":2},"datasetVersion":"2026-09-14T16:17:12.679Z"}