# Buggy code
def from_name(
    collection, apis, requirement, force, parent=None, allow_pre_release=False
):
    namespace, name = collection.split(".", 1)
    galaxy_meta = None

    for api in apis:
        try:
            if not (
                requirement == "*"
                or requirement.startswith("<")
                or requirement.startswith(">")
                or requirement.startswith("!=")
            ):
                # Exact requirement
                allow_pre_release = True

                if requirement.startswith("="):
                    requirement = requirement.lstrip("=")

                resp = api.get_collection_version_metadata(namespace, name, requirement)

                galaxy_meta = resp
                versions = [resp.version]
            else:
                versions = api.get_collection_versions(namespace, name)
        except GalaxyError as err:
            if err.http_code == 404:
                display.vvv(
                    "Collection '%s' is not available from server %s %s"
                    % (collection, api.name, api.api_server)
                )
                continue
            raise

        display.vvv(
            "Collection '%s' obtained from server %s %s"
            % (collection, api.name, api.api_server)
        )
        break
    else:
        raise AnsibleError(
            "Failed to find collection %s:%s" % (collection, requirement)
        )

    req = CollectionRequirement(
        namespace,
        name,
        None,
        api,
        versions,
        requirement,
        force,
        parent=parent,
        metadata=galaxy_meta,
        allow_pre_releases=allow_pre_release,
    )
    return req


# Traceback (urllib.error.HTTPError)
ansible-galaxy collection install servicenow.servicenow -vvv
ansible-galaxy 2.9.11
config file = /Users/pgriffit/ansible.cfg
configured module search path = ['/Users/pgriffit/.ansible/plugins/modules', '/usr/share/ansible/plugins/modules']
ansible python module location = /usr/local/lib/python3.8/site-packages/ansible
executable location = /usr/local/bin/ansible-galaxy
python version = 3.8.5 (default, Jul 21 2020, 10:48:26) [Clang 11.0.3 (clang-1103.0.32.62)]
Using /Users/pgriffit/ansible.cfg as config file
Found installed collection f5networks.f5_modules:1.1.0 at '/Users/pgriffit/collections/ansible_collections/f5networks/f5_modules'
Found installed collection ansible.posix:1.1.0 at '/Users/pgriffit/collections/ansible_collections/ansible/posix'
Found installed collection ansible.netcommon:0.0.2 at '/Users/pgriffit/collections/ansible_collections/ansible/netcommon'
Found installed collection junipernetworks.junos:0.0.2 at '/Users/pgriffit/collections/ansible_collections/junipernetworks/junos'
Found installed collection servicenow.servicenow:1.0.1 at '/Users/pgriffit/collections/ansible_collections/servicenow/servicenow'
Process install dependency map
Processing requirement collection 'servicenow.servicenow'
ERROR! Unexpected Exception, this is probably a bug: HTTP Error 400: Bad Request
the full traceback was:

Traceback (most recent call last):
File "/usr/local/bin/ansible-galaxy", line 123, in <module>
exit_code = cli.run()
File "/usr/local/lib/python3.8/site-packages/ansible/cli/galaxy.py", line 376, in run
context.CLIARGS['func']()
File "/usr/local/lib/python3.8/site-packages/ansible/cli/galaxy.py", line 851, in execute_install
install_collections(requirements, output_path, self.api_servers, (not ignore_certs), ignore_errors,
File "/usr/local/lib/python3.8/site-packages/ansible/galaxy/collection.py", line 457, in install_collections
dependency_map = _build_dependency_map(collections, existing_collections, b_temp_path, apis,
File "/usr/local/lib/python3.8/site-packages/ansible/galaxy/collection.py", line 821, in _build_dependency_map
_get_collection_info(dependency_map, existing_collections, name, version, source, b_temp_path, apis,
File "/usr/local/lib/python3.8/site-packages/ansible/galaxy/collection.py", line 894, in _get_collection_info
collection_info = CollectionRequirement.from_name(collection, apis, requirement, force, parent=parent)
File "/usr/local/lib/python3.8/site-packages/ansible/galaxy/collection.py", line 346, in from_name
resp = api.get_collection_versions(namespace, name)
File "/usr/local/lib/python3.8/site-packages/ansible/galaxy/api.py", line 56, in wrapped
data = self._call_galaxy(n_url, method='GET', error_context_msg=error_context_msg)
File "/usr/local/lib/python3.8/site-packages/ansible/galaxy/api.py", line 192, in _call_galaxy
self._add_auth_token(headers, url, required=auth_required)
File "/usr/local/lib/python3.8/site-packages/ansible/galaxy/api.py", line 222, in _add_auth_token
headers.update(self.token.headers())
File "/usr/local/lib/python3.8/site-packages/ansible/galaxy/token.py", line 94, in headers
headers['Authorization'] = '%s %s' % (self.token_type, self.get())
File "/usr/local/lib/python3.8/site-packages/ansible/galaxy/token.py", line 77, in get
resp = open_url(to_native(self.auth_url),
File "/usr/local/lib/python3.8/site-packages/ansible/module_utils/urls.py", line 1384, in open_url
return Request().open(method, url, data=data, headers=headers, use_proxy=use_proxy,
File "/usr/local/lib/python3.8/site-packages/ansible/module_utils/urls.py", line 1294, in open
r = urllib_request.urlopen(*urlopen_args)
File "/usr/local/Cellar/python@3.8/3.8.5/Frameworks/Python.framework/Versions/3.8/lib/python3.8/urllib/request.py", line 222, in urlopen
return opener.open(url, data, timeout)
File "/usr/local/Cellar/python@3.8/3.8.5/Frameworks/Python.framework/Versions/3.8/lib/python3.8/urllib/request.py", line 531, in open
response = meth(req, response)
File "/usr/local/Cellar/python@3.8/3.8.5/Frameworks/Python.framework/Versions/3.8/lib/python3.8/urllib/request.py", line 640, in http_response
response = self.parent.error(
File "/usr/local/Cellar/python@3.8/3.8.5/Frameworks/Python.framework/Versions/3.8/lib/python3.8/urllib/request.py", line 569, in error
return self._call_chain(*args)
File "/usr/local/Cellar/python@3.8/3.8.5/Frameworks/Python.framework/Versions/3.8/lib/python3.8/urllib/request.py", line 502, in _call_chain
result = func(*args)
File "/usr/local/Cellar/python@3.8/3.8.5/Frameworks/Python.framework/Versions/3.8/lib/python3.8/urllib/request.py", line 649, in http_error_default
raise HTTPError(req.full_url, code, msg, hdrs, fp)
urllib.error.HTTPError: HTTP Error 400: Bad Request

# Fixed code
def from_name(
    collection, apis, requirement, force, parent=None, allow_pre_release=False
):
    namespace, name = collection.split(".", 1)
    galaxy_meta = None

    for api in apis:
        try:
            if not (
                requirement == "*"
                or requirement.startswith("<")
                or requirement.startswith(">")
                or requirement.startswith("!=")
            ):
                # Exact requirement
                allow_pre_release = True

                if requirement.startswith("="):
                    requirement = requirement.lstrip("=")

                resp = api.get_collection_version_metadata(namespace, name, requirement)

                galaxy_meta = resp
                versions = [resp.version]
            else:
                versions = api.get_collection_versions(namespace, name)
        except GalaxyError as err:
            if err.http_code != 404:
                raise

            versions = []

        # Automation Hub doesn't return a 404 but an empty version list so we check that to align both AH and
        # Galaxy when the collection is not available on that server.
        if not versions:
            display.vvv(
                "Collection '%s' is not available from server %s %s"
                % (collection, api.name, api.api_server)
            )
            continue

        display.vvv(
            "Collection '%s' obtained from server %s %s"
            % (collection, api.name, api.api_server)
        )
        break
    else:
        raise AnsibleError(
            "Failed to find collection %s:%s" % (collection, requirement)
        )

    req = CollectionRequirement(
        namespace,
        name,
        None,
        api,
        versions,
        requirement,
        force,
        parent=parent,
        metadata=galaxy_meta,
        allow_pre_releases=allow_pre_release,
    )
    return req