{"record":{"id":"85d959b49af95e31","repo":"apache/beam","slug":"f-provider-file-source-path-must-be-a-list-of-providers","errorCode":null,"errorMessage":"f\"Provider file {source_path} must be a list of Providers\"","messagePattern":"f\"Provider file (.+?) must be a list of Providers\"","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"sdks/python/apache_beam/yaml/yaml_provider.py","lineNumber":1652,"sourceCode":"    return FileSystems.join(FileSystems.split(base)[0], path)\n\n\ndef _read_url_or_filepath(path):\n  scheme = urllib.parse.urlparse(path, '').scheme\n  if scheme and scheme in urllib.parse.uses_netloc:\n    with urllib.request.urlopen(path) as response:\n      return response.read()\n  else:\n    with FileSystems.open(path) as fin:\n      return fin.read()\n\n\ndef load_providers(source_path: str) -> Iterable[Provider]:\n  from apache_beam.yaml.yaml_transform import SafeLineLoader\n  provider_specs = yaml.load(\n      _read_url_or_filepath(source_path), Loader=SafeLineLoader)\n  if not isinstance(provider_specs, list):\n    raise ValueError(f\"Provider file {source_path} must be a list of Providers\")\n  return parse_providers(source_path, provider_specs)\n\n\n@_as_list\ndef parse_providers(source_path,\n                    provider_specs: Iterable[Mapping]) -> Iterable[Provider]:\n  from apache_beam.yaml.yaml_transform import SafeLineLoader\n  for provider_spec in provider_specs:\n    if 'include' in provider_spec:\n      if len(SafeLineLoader.strip_metadata(provider_spec)) != 1:\n        raise ValueError(\n            f\"When using include, it must be the only parameter: \"\n            f\"{provider_spec} \"\n            f\"at {source_path}:{SafeLineLoader.get_line(provider_spec)}\")\n      include_path = _join_url_or_filepath(\n          source_path, provider_spec['include'])\n      try:\n        yield from load_providers(include_path)","sourceCodeStart":1634,"sourceCodeEnd":1670,"githubUrl":"https://github.com/apache/beam/blob/12126d8942aaf848030c478b4c6a28c6af861c66/sdks/python/apache_beam/yaml/yaml_provider.py#L1634-L1670","documentation":"load_providers() loads a YAML provider file and expects the top-level YAML document to be a list of provider specifications. If the parsed document is not a list (e.g. a mapping or scalar), a ValueError is raised because parse_providers cannot iterate provider specs.","triggerScenarios":"Calling load_providers(path) or passing --provider_config_file where the YAML file's root is a mapping (e.g. 'providers:' wrapper key) or a single scalar instead of a top-level YAML sequence of provider specs.","commonSituations":"Users wrap provider definitions under a top-level key like 'providers:', copy a JSON object instead of a list, or merge multiple provider files into a dict.","solutions":["Make the YAML file's root a list of provider specs (start with '- type: ...').","Remove any top-level wrapper key such as 'providers:' so entries are at the document root.","Convert a single provider spec into a one-element list.","Validate the file with yaml.safe_load and assert isinstance(result, list) before passing it to Beam YAML."],"exampleFix":"# before (providers.yaml)\nproviders:\n  - type: Sql\n    config: {}\n\n# after\n- type: Sql\n  config: {}","handlingStrategy":"validation","validationCode":"import yaml\nspecs = yaml.safe_load(open(path))\nif not isinstance(specs, list):\n    raise ValueError(f'{path}: provider file root must be a list, got {type(specs).__name__}')","typeGuard":"def is_provider_list(specs) -> bool:\n    return isinstance(specs, list) and all(isinstance(s, dict) for s in specs)","tryCatchPattern":null,"preventionTips":["Keep provider YAML roots as top-level sequences, no wrapper keys","Run yaml.safe_load on the file and assert a list before invoking Beam YAML","Lint provider files in CI"],"tags":["yaml","python","apache-beam","provider-config"],"backgroundTag":"invalid-argument-format","analyzedSha":"12126d8942aaf848030c478b4c6a28c6af861c66","analyzedAt":"2026-09-13T01:50:10.254Z","contentChangedAt":"2026-09-13T01:50:10.254Z","schemaVersion":2},"datasetVersion":"2026-09-14T21:17:11.552Z"}