# Buggy code
def cache_node_list(nodes, provider, opts):
    """
    If configured to do so, update the cloud cachedir with the current list of
    nodes. Also fires configured events pertaining to the node list.

    .. versionadded:: 2014.7.0
    """
    if "update_cachedir" not in opts or not opts["update_cachedir"]:
        return

    base = os.path.join(init_cachedir(), "active")
    driver = next(six.iterkeys(opts["providers"][provider]))
    prov_dir = os.path.join(base, driver, provider)
    if not os.path.exists(prov_dir):
        os.makedirs(prov_dir)

    # Check to see if any nodes in the cache are not in the new list
    missing_node_cache(prov_dir, nodes, provider, opts)

    for node in nodes:
        diff_node_cache(prov_dir, node, nodes[node], opts)
        path = os.path.join(prov_dir, "{0}.p".format(node))
        with salt.utils.files.fopen(path, "w") as fh_:
            msgpack.dump(nodes[node], fh_)


# Traceback (TypeError)
[ERROR   ] An un-handled exception was caught by salt's global exception handler:
TypeError: a bytes-like object is required, not 'str'
Traceback (most recent call last):
File "/home/bar/Dev/foo/build7/_venv/bin/salt-ssh", line 11, in <module>
load_entry_point('salt==2017.7.2', 'console_scripts', 'salt-ssh')()
File "/home/bar/Dev/foo/build7/_venv/lib/python3.5/site-packages/salt/scripts.py", line 416, in salt_ssh
client.run()
File "/home/bar/Dev/foo/build7/_venv/lib/python3.5/site-packages/salt/cli/ssh.py", line 20, in run
ssh = salt.client.ssh.SSH(self.config)
File "/home/bar/Dev/foo/build7/_venv/lib/python3.5/site-packages/salt/client/ssh/__init__.py", line 230, in __init__
self.tgt_type)
File "/home/bar/Dev/foo/build7/_venv/lib/python3.5/site-packages/salt/roster/__init__.py", line 105, in targets
targets.update(self.rosters[f_str](tgt, tgt_type))
File "/home/bar/Dev/foo/build7/_venv/lib/python3.5/site-packages/salt/roster/cloud.py", line 45, in targets
minions = __runner__['cache.cloud'](tgt)
File "/home/bar/Dev/foo/build7/_venv/lib/python3.5/site-packages/salt/runners/cache.py", line 402, in cloud
cloud_cache = __utils__['cloud.list_cache_nodes_full'](opts=opts, provider=provider)
File "/home/bar/Dev/foo/build7/_venv/lib/python3.5/site-packages/salt/utils/cloud.py", line 2768, in list_cache_nodes_full
minions[driver][prov][minion_id] = msgpack.load(fh_)
File "msgpack/_unpacker.pyx", line 164, in msgpack._unpacker.unpack (msgpack/_unpacker.cpp:2622)
File "msgpack/_unpacker.pyx", line 124, in msgpack._unpacker.unpackb (msgpack/_unpacker.cpp:1918)
TypeError: a bytes-like object is required, not 'str'
Traceback (most recent call last):
File "/home/bar/Dev/foo/build7/_venv/bin/salt-ssh", line 11, in <module>
load_entry_point('salt==2017.7.2', 'console_scripts', 'salt-ssh')()
File "/home/bar/Dev/foo/build7/_venv/lib/python3.5/site-packages/salt/scripts.py", line 416, in salt_ssh
client.run()
File "/home/bar/Dev/foo/build7/_venv/lib/python3.5/site-packages/salt/cli/ssh.py", line 20, in run
ssh = salt.client.ssh.SSH(self.config)
File "/home/bar/Dev/foo/build7/_venv/lib/python3.5/site-packages/salt/client/ssh/__init__.py", line 230, in __init__
self.tgt_type)
File "/home/bar/Dev/foo/build7/_venv/lib/python3.5/site-packages/salt/roster/__init__.py", line 105, in targets
targets.update(self.rosters[f_str](tgt, tgt_type))
File "/home/bar/Dev/foo/build7/_venv/lib/python3.5/site-packages/salt/roster/cloud.py", line 45, in targets
minions = __runner__['cache.cloud'](tgt)
File "/home/bar/Dev/foo/build7/_venv/lib/python3.5/site-packages/salt/runners/cache.py", line 402, in cloud
cloud_cache = __utils__['cloud.list_cache_nodes_full'](opts=opts, provider=provider)
File "/home/bar/Dev/foo/build7/_venv/lib/python3.5/site-packages/salt/utils/cloud.py", line 2768, in list_cache_nodes_full
minions[driver][prov][minion_id] = msgpack.load(fh_)
File "msgpack/_unpacker.pyx", line 164, in msgpack._unpacker.unpack (msgpack/_unpacker.cpp:2622)
File "msgpack/_unpacker.pyx", line 124, in msgpack._unpacker.unpackb (msgpack/_unpacker.cpp:1918)
TypeError: a bytes-like object is required, not 'str'
EXIT 1

# Fixed code
def cache_node_list(nodes, provider, opts):
    """
    If configured to do so, update the cloud cachedir with the current list of
    nodes. Also fires configured events pertaining to the node list.

    .. versionadded:: 2014.7.0
    """
    if "update_cachedir" not in opts or not opts["update_cachedir"]:
        return

    base = os.path.join(init_cachedir(), "active")
    driver = next(six.iterkeys(opts["providers"][provider]))
    prov_dir = os.path.join(base, driver, provider)
    if not os.path.exists(prov_dir):
        os.makedirs(prov_dir)

    # Check to see if any nodes in the cache are not in the new list
    missing_node_cache(prov_dir, nodes, provider, opts)

    for node in nodes:
        diff_node_cache(prov_dir, node, nodes[node], opts)
        path = os.path.join(prov_dir, "{0}.p".format(node))
        mode = "wb" if six.PY3 else "w"
        with salt.utils.files.fopen(path, mode) as fh_:
            msgpack.dump(nodes[node], fh_)