ansible/ansible · error · AnsibleError

Expecting requirements file to be a dict with the key 'colle

Error message

Expecting requirements file to be a dict with the key 'collections' that contains a list of collections to install

What it means

Raised by _parse_requirements_file when the requirements YAML is a plain list (the old role-only format) but allow_old_format is False. Collection-oriented subcommands (install via _require_one_of_collections_requirements, download, etc.) pass allow_old_format=False and therefore demand the modern dict format with 'collections'/'roles' keys.

Source

Thrown at lib/ansible/cli/galaxy.py:808

                return [GalaxyRole(self.galaxy, self.lazy_role_api, **role)]
            else:
                b_include_path = to_bytes(requirement["include"], errors="surrogate_or_strict")
                if not os.path.isfile(b_include_path):
                    raise AnsibleError("Failed to find include requirements file '%s' in '%s'"
                                       % (to_native(b_include_path), to_native(requirements_file)))

                with open(b_include_path, 'rb') as f_include:
                    try:
                        return [GalaxyRole(self.galaxy, self.lazy_role_api, **r) for r in
                                (RoleRequirement.role_yaml_parse(i) for i in yaml_load(f_include))]
                    except Exception as e:
                        raise AnsibleError("Unable to load data from include requirements file: %s %s"
                                           % (to_native(requirements_file), to_native(e)))

        if isinstance(file_requirements, list):
            # Older format that contains only roles
            if not allow_old_format:
                raise AnsibleError("Expecting requirements file to be a dict with the key 'collections' that contains "
                                   "a list of collections to install")

            for role_req in file_requirements:
                requirements['roles'] += parse_role_req(role_req)

        elif isinstance(file_requirements, dict):
            # Newer format with a collections and/or roles key
            extra_keys = set(file_requirements.keys()).difference(set(['roles', 'collections']))
            if extra_keys:
                raise AnsibleError("Expecting only 'roles' and/or 'collections' as base keys in the requirements "
                                   "file. Found: %s" % (to_native(", ".join(extra_keys))))

            for role_req in file_requirements.get('roles') or []:
                requirements['roles'] += parse_role_req(role_req)

            requirements['collections'] = [
                Requirement.from_requirement_dict(
                    self._init_coll_req_dict(collection_req),

View on GitHub (pinned to 9cf16a4aca)

Solutions

  1. Convert the file to the modern format: wrap roles under a 'roles:' key and put collections under 'collections:'.
  2. If you only want roles installed, invoke 'ansible-galaxy role install -r requirements.yml' which still allows the old list format.
  3. If both roles and collections are needed, use 'ansible-galaxy install -r requirements.yml' (implicit mode) with a dict-format file containing both keys.

Example fix

# before (requirements.yml)
- src: geerlingguy.docker

# after
roles:
  - name: geerlingguy.docker
collections:
  - community.general
Defensive patterns

Strategy: validation

Validate before calling

import yaml

data = yaml.safe_load(open("requirements.yml"))
if isinstance(data, list):
    raise SystemExit("requirements.yml uses the old role-list format; "
                     "wrap entries under a 'roles:' key (and 'collections:' for collections)")

Type guard

def is_modern_requirements(data) -> bool:
    return isinstance(data, dict) and ('roles' in data or 'collections' in data)

Prevention

When it happens

Trigger: Running 'ansible-galaxy collection install -r requirements.yml' where requirements.yml is a bare list of roles ('- src: git+...'), or 'ansible-galaxy install -r file.yml' in the implicit-collection mode that calls _parse_requirements_file with allow_old_format=False at lib/ansible/cli/galaxy.py:808.

Common situations: Teams upgrade ansible and reuse an old role-only requirements.yml with 'ansible-galaxy collection install'; CI scripts that switched from 'ansible-galaxy install' to 'collection install' without migrating the requirements file format.

Related errors


AI-assisted analysis of ansible/ansible@9cf16a4aca (2026-08-15). Data as JSON: /api/errors/e997d6e7dcbcf7d2. Report an issue: GitHub.