# Buggy code
def disbatch(self):
    """
    Disbatch all lowstates to the appropriate clients
    """
    ret = []

    # check clients before going, we want to throw 400 if one is bad
    for low in self.lowstate:
        if not self._verify_client(low):
            return

        # Make sure we have 'token' or 'username'/'password' in each low chunk.
        # Salt will verify the credentials are correct.
        if self.token is not None and "token" not in low:
            low["token"] = self.token

        if not (
            ("token" in low)
            or ("username" in low and "password" in low and "eauth" in low)
        ):
            ret.append("Failed to authenticate")
            break

        # disbatch to the correct handler
        try:
            chunk_ret = yield getattr(self, "_disbatch_{0}".format(low["client"]))(low)
            ret.append(chunk_ret)
        except (AuthenticationError, AuthorizationError, EauthAuthenticationError):
            ret.append("Failed to authenticate")
            break
        except Exception as ex:  # pylint: disable=broad-except
            ret.append("Unexpected exception while handling request: {0}".format(ex))
            log.error("Unexpected exception while handling request:", exc_info=True)

    self.write(self.serialize({"return": ret}))
    self.finish()


# Traceback (TypeError)
2018-09-07 19:06:22,631 [tornado.application:1495][ERROR   ][998] Uncaught exception POST /run (127.0.0.1)
HTTPServerRequest(protocol='http', host='localhost:8000', method='POST', uri='/run', version='HTTP/1.1', remote_ip='127.0.0.1', headers={'Host': 'localhost:8000', 'Content-Type': 'application/json', 'Content-Length': '125', 'Accept': 'application/x-yaml', 'User-Agent': 'curl/7.29.0'})
Traceback (most recent call last):
File "/usr/lib64/python2.7/site-packages/tornado/web.py", line 1368, in _stack_context_handle_exception
raise_exc_info((type, value, traceback))
File "/usr/lib64/python2.7/site-packages/tornado/stack_context.py", line 313, in wrapped
ret = fn(*args, **kwargs)
File "/usr/lib64/python2.7/site-packages/tornado/gen.py", line 770, in <lambda>
IOLoop.current().call_later(duration, lambda: f.set_result(None))
File "/usr/lib64/python2.7/site-packages/tornado/concurrent.py", line 253, in set_result
self._set_done()
File "/usr/lib64/python2.7/site-packages/tornado/concurrent.py", line 297, in _set_done
for cb in self._callbacks:
TypeError: 'NoneType' object is not iterable

# Fixed code
def disbatch(self):
    """
    Disbatch all lowstates to the appropriate clients
    """
    ret = []

    # check clients before going, we want to throw 400 if one is bad
    for low in self.lowstate:
        if not self._verify_client(low):
            return

        # Make sure we have 'token' or 'username'/'password' in each low chunk.
        # Salt will verify the credentials are correct.
        if self.token is not None and "token" not in low:
            low["token"] = self.token

        if not (
            ("token" in low)
            or ("username" in low and "password" in low and "eauth" in low)
        ):
            ret.append("Failed to authenticate")
            break

        # disbatch to the correct handler
        try:
            chunk_ret = yield getattr(self, "_disbatch_{}".format(low["client"]))(low)
            ret.append(chunk_ret)
        except (AuthenticationError, AuthorizationError, EauthAuthenticationError):
            ret.append("Failed to authenticate")
            break
        except Exception as ex:  # pylint: disable=broad-except
            ret.append("Unexpected exception while handling request: {}".format(ex))
            log.error("Unexpected exception while handling request:", exc_info=True)

    self.write(self.serialize({"return": ret}))
    self.finish()