# Buggy code
def _check_max_running(self, func, data, opts, now):
    """
    Return the schedule data structure
    """
    # Check to see if there are other jobs with this
    # signature running.  If there are more than maxrunning
    # jobs present then don't start another.
    # If jid_include is False for this job we can ignore all this
    # NOTE--jid_include defaults to True, thus if it is missing from the data
    # dict we treat it like it was there and is True

    # Check if we're able to run
    if not data["run"]:
        return data
    if "jid_include" not in data or data["jid_include"]:
        jobcount = 0
        if self.opts["__role"] == "master":
            current_jobs = salt.utils.master.get_running_jobs(self.opts)
        else:
            current_jobs = salt.utils.minion.running(self.opts)
        for job in current_jobs:
            if "schedule" in job:
                log.debug(
                    "schedule.handle_func: Checking job against fun %s: %s", func, job
                )
                if data["name"] == job["schedule"] and salt.utils.process.os_is_running(
                    job["pid"]
                ):
                    jobcount += 1
                    log.debug(
                        "schedule.handle_func: Incrementing jobcount, "
                        "now %s, maxrunning is %s",
                        jobcount,
                        data["maxrunning"],
                    )
                    if jobcount >= data["maxrunning"]:
                        log.debug(
                            "schedule.handle_func: The scheduled job "
                            "%s was not started, %s already running",
                            data["name"],
                            data["maxrunning"],
                        )
                        data["_skip_reason"] = "maxrunning"
                        data["_skipped"] = True
                        data["_skipped_time"] = now
                        data["run"] = False
                        return data
    return data


# Traceback (KeyError)
2019-09-25 14:06:41,391 [salt.utils.schedule:461 ][INFO    ][6910] Running Job: test-scheduler-present
2019-09-25 14:06:41,391 [tornado.application:611 ][ERROR   ][6910] Exception in callback <functools.partial object at 0x7f5bcc528520>
Traceback (most recent call last):
File "/usr/lib64/python2.7/site-packages/tornado/ioloop.py", line 591, in _run_callback
ret = callback()
File "/usr/lib64/python2.7/site-packages/tornado/stack_context.py", line 274, in null_wrapper
return fn(*args, **kwargs)
File "/usr/lib64/python2.7/site-packages/tornado/ioloop.py", line 597, in <lambda>
self.add_future(ret, lambda f: f.result())
File "/usr/lib64/python2.7/site-packages/tornado/concurrent.py", line 214, in result
raise_exc_info(self._exc_info)
File "/usr/lib64/python2.7/site-packages/tornado/gen.py", line 888, in run
yielded = self.gen.throw(*exc_info)
File "/usr/lib/python2.7/site-packages/salt/minion.py", line 959, in handle_event
yield [minion.handle_event(package) for minion in self.minions]
File "/usr/lib64/python2.7/site-packages/tornado/gen.py", line 882, in run
value = future.result()
File "/usr/lib64/python2.7/site-packages/tornado/concurrent.py", line 214, in result
raise_exc_info(self._exc_info)
File "/usr/lib64/python2.7/site-packages/tornado/gen.py", line 668, in callback
result_list.append(f.result())
File "/usr/lib64/python2.7/site-packages/tornado/concurrent.py", line 214, in result
raise_exc_info(self._exc_info)
File "/usr/lib64/python2.7/site-packages/tornado/gen.py", line 232, in wrapper
yielded = next(result)
File "/usr/lib/python2.7/site-packages/salt/minion.py", line 2371, in handle_event
self.manage_schedule(tag, data)
File "/usr/lib/python2.7/site-packages/salt/minion.py", line 2233, in manage_schedule
self.schedule.run_job(name)
File "/usr/lib/python2.7/site-packages/salt/utils/schedule.py", line 467, in run_job
datetime.datetime.now())
File "/usr/lib/python2.7/site-packages/salt/utils/schedule.py", line 212, in _check_max_running
if not data['run']:
KeyError: u'run'

# Fixed code
def _check_max_running(self, func, data, opts, now):
    """
    Return the schedule data structure
    """
    # Check to see if there are other jobs with this
    # signature running.  If there are more than maxrunning
    # jobs present then don't start another.
    # If jid_include is False for this job we can ignore all this
    # NOTE--jid_include defaults to True, thus if it is missing from the data
    # dict we treat it like it was there and is True

    # Check if we're able to run
    if "run" not in data or not data["run"]:
        return data
    if "jid_include" not in data or data["jid_include"]:
        jobcount = 0
        if self.opts["__role"] == "master":
            current_jobs = salt.utils.master.get_running_jobs(self.opts)
        else:
            current_jobs = salt.utils.minion.running(self.opts)
        for job in current_jobs:
            if "schedule" in job:
                log.debug(
                    "schedule.handle_func: Checking job against fun %s: %s", func, job
                )
                if data["name"] == job["schedule"] and salt.utils.process.os_is_running(
                    job["pid"]
                ):
                    jobcount += 1
                    log.debug(
                        "schedule.handle_func: Incrementing jobcount, "
                        "now %s, maxrunning is %s",
                        jobcount,
                        data["maxrunning"],
                    )
                    if jobcount >= data["maxrunning"]:
                        log.debug(
                            "schedule.handle_func: The scheduled job "
                            "%s was not started, %s already running",
                            data["name"],
                            data["maxrunning"],
                        )
                        data["_skip_reason"] = "maxrunning"
                        data["_skipped"] = True
                        data["_skipped_time"] = now
                        data["run"] = False
                        return data
    return data