{"record":{"id":"bec11d024c800070","repo":"ansible/ansible","slug":"unable-to-load-data-from-include-requirements-file","errorCode":null,"errorMessage":"Unable to load data from include requirements file: %s %s","messagePattern":"Unable to load data from include requirements file: (.+?) (.+?)","errorType":"exception","errorClass":"AnsibleError","httpStatus":null,"severity":"error","filePath":"lib/ansible/cli/galaxy.py","lineNumber":802,"sourceCode":"        def parse_role_req(requirement):\n            if \"include\" not in requirement:\n                role = RoleRequirement.role_yaml_parse(requirement)\n                display.vvv(\"found role %s in yaml file\" % to_text(role))\n                if \"name\" not in role and \"src\" not in role:\n                    raise AnsibleError(\"Must specify name or src for role\")\n                return [GalaxyRole(self.galaxy, self.lazy_role_api, **role)]\n            else:\n                b_include_path = to_bytes(requirement[\"include\"], errors=\"surrogate_or_strict\")\n                if not os.path.isfile(b_include_path):\n                    raise AnsibleError(\"Failed to find include requirements file '%s' in '%s'\"\n                                       % (to_native(b_include_path), to_native(requirements_file)))\n\n                with open(b_include_path, 'rb') as f_include:\n                    try:\n                        return [GalaxyRole(self.galaxy, self.lazy_role_api, **r) for r in\n                                (RoleRequirement.role_yaml_parse(i) for i in yaml_load(f_include))]\n                    except Exception as e:\n                        raise AnsibleError(\"Unable to load data from include requirements file: %s %s\"\n                                           % (to_native(requirements_file), to_native(e)))\n\n        if isinstance(file_requirements, list):\n            # Older format that contains only roles\n            if not allow_old_format:\n                raise AnsibleError(\"Expecting requirements file to be a dict with the key 'collections' that contains \"\n                                   \"a list of collections to install\")\n\n            for role_req in file_requirements:\n                requirements['roles'] += parse_role_req(role_req)\n\n        elif isinstance(file_requirements, dict):\n            # Newer format with a collections and/or roles key\n            extra_keys = set(file_requirements.keys()).difference(set(['roles', 'collections']))\n            if extra_keys:\n                raise AnsibleError(\"Expecting only 'roles' and/or 'collections' as base keys in the requirements \"\n                                   \"file. Found: %s\" % (to_native(\", \".join(extra_keys))))\n","sourceCodeStart":784,"sourceCodeEnd":820,"githubUrl":"https://github.com/ansible/ansible/blob/9cf16a4aca7898481c257f1e17ad28d0b67b1f85/lib/ansible/cli/galaxy.py#L784-L820","documentation":"Raised as a catch-all when an included requirements file (the legacy 'include:' mechanism) exists and was opened, but either its YAML could not be parsed or a role entry inside it failed to parse (the list comprehension calling RoleRequirement.role_yaml_parse is wrapped in a bare 'except Exception'). The original exception text is appended so the root cause is visible.","triggerScenarios":"An 'include:' file whose contents are invalid YAML, or whose entries are not valid role specifications (e.g. a list of scalars that role_yaml_parse cannot interpret, or an unexpected exception while constructing GalaxyRole kwargs) triggers the except at lib/ansible/cli/galaxy.py:802.","commonSituations":"The included file was written in the newer dict format ('collections:' key) while the include mechanism expects a plain list of roles; partially written/truncated file from a concurrent process; wrong file substituted with the same name.","solutions":["Read the appended original error in the message — it names the real failure (YAML syntax vs role parsing).","Ensure the included file is a YAML list of role entries (name/src), not the newer requirements dict format.","Lint the included file standalone with ansible-galaxy or a YAML parser to find the offending entry.","Inline the roles into the parent file to remove the include indirection."],"exampleFix":"# before (common.yml uses new format but is consumed via include:)\ncollections:\n  - community.general\n\n# after (common.yml must be a plain role list)\n- name: geerlingguy.docker\n- name: bertvv.samba\n","handlingStrategy":"validation","validationCode":"import yaml\n\ndef validate_included_roles(path):\n    data = yaml.safe_load(open(path))\n    assert isinstance(data, list), \"included file must be a YAML list of role entries\"\n    for e in data:\n        assert isinstance(e, (str, dict)), f\"bad role entry: {e!r}\"\n","typeGuard":null,"tryCatchPattern":"try:\n    subprocess.run(cmd, check=True)\nexcept subprocess.CalledProcessError as e:\n    # message embeds the original parse error; surface it, fix the include file, re-run\n    print(e.stderr)\n","preventionTips":["Keep included files in the plain role-list format; never put 'collections:' keys in them.","Lint every included file the same way as the parent requirements file.","Inline roles into the parent file to remove an entire failure class."],"tags":["ansible-galaxy","roles","include","yaml","parse-error"],"backgroundTag":null,"analyzedSha":"9cf16a4aca7898481c257f1e17ad28d0b67b1f85","analyzedAt":"2026-08-15T00:15:47.100Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}