# Buggy code
def list_valid_collection_paths(search_paths=None, warn=False):
    """
    Filter out non existing or invalid search_paths for collections
    :param search_paths: list of text-string paths, if none load default config
    :param warn: display warning if search_path does not exist
    :return: subset of original list
    """

    if search_paths is None:
        search_paths = AnsibleCollectionLoader().n_collection_paths

    for path in search_paths:
        if not os.path.exists(path):
            # warn for missing, but not if default
            if warn:
                display.warning(
                    "The configured collection path {0} does not exist.".format(path)
                )
            continue

        if not os.path.isdir(path):
            if warn:
                display.warning(
                    "The configured collection path {0}, exists, but it is not a directory.".format(
                        path
                    )
                )
            continue

        yield path


# Traceback (TypeError)
ansible-doc 2.9.7.post0
config file = None
configured module search path = ['/.ansible/plugins/modules', '/usr/share/ansible/plugins/modules']
ansible python module location = /ansible/lib/ansible
executable location = /ansible/bin/ansible-doc
python version = 3.8.2 (default, Apr  8 2020, 14:31:25) [GCC 9.3.0]
No config file found; using defaults
/ansible/lib/ansible/cli/doc.py:219: YAMLLoadWarning: calling yaml.load() without Loader=... is deprecated, as the default Loader is unsafe. Please read https://msg.pyyaml.org/load for full details.
doc_data['return'] = yaml.load(doc_data['return'])
ERROR! Unexpected Exception, this is probably a bug: Object of type datetime is not JSON serializable
the full traceback was:

Traceback (most recent call last):
File "/ansible/bin/ansible-doc", line 123, in <module>
exit_code = cli.run()
File "/ansible/lib/ansible/cli/doc.py", line 223, in run
jdump(plugin_docs)
File "/ansible/lib/ansible/cli/doc.py", line 36, in jdump
display.display(json.dumps(text, sort_keys=True, indent=4))
File "/usr/lib/python3.8/json/__init__.py", line 234, in dumps
return cls(
File "/usr/lib/python3.8/json/encoder.py", line 201, in encode
chunks = list(chunks)
File "/usr/lib/python3.8/json/encoder.py", line 431, in _iterencode
yield from _iterencode_dict(o, _current_indent_level)
File "/usr/lib/python3.8/json/encoder.py", line 405, in _iterencode_dict
yield from chunks
File "/usr/lib/python3.8/json/encoder.py", line 405, in _iterencode_dict
yield from chunks
File "/usr/lib/python3.8/json/encoder.py", line 405, in _iterencode_dict
yield from chunks
[Previous line repeated 1 more time]
File "/usr/lib/python3.8/json/encoder.py", line 325, in _iterencode_list
yield from chunks
File "/usr/lib/python3.8/json/encoder.py", line 405, in _iterencode_dict
yield from chunks
File "/usr/lib/python3.8/json/encoder.py", line 438, in _iterencode
o = _default(o)
File "/usr/lib/python3.8/json/encoder.py", line 179, in default
raise TypeError(f'Object of type {o.__class__.__name__} '
TypeError: Object of type datetime is not JSON serializable

# Fixed code
def list_valid_collection_paths(search_paths=None, warn=False):
    """
    Filter out non existing or invalid search_paths for collections
    :param search_paths: list of text-string paths, if none load default config
    :param warn: display warning if search_path does not exist
    :return: subset of original list
    """

    if search_paths is None:
        search_paths = []

    search_paths.extend(AnsibleCollectionLoader().n_collection_paths)

    for path in search_paths:
        b_path = to_bytes(path)
        if not os.path.exists(b_path):
            # warn for missing, but not if default
            if warn:
                display.warning(
                    "The configured collection path {0} does not exist.".format(path)
                )
            continue

        if not os.path.isdir(b_path):
            if warn:
                display.warning(
                    "The configured collection path {0}, exists, but it is not a directory.".format(
                        path
                    )
                )
            continue

        yield path