# Buggy code
def _run_check(self, low_data):
    """
    Check that unless doesn't return 0, and that onlyif returns a 0.
    """
    ret = {"result": False}
    cmd_opts = {}

    if "shell" in self.opts["grains"]:
        cmd_opts["shell"] = self.opts["grains"].get("shell")
    if "onlyif" in low_data:
        if not isinstance(low_data["onlyif"], list):
            low_data_onlyif = [low_data["onlyif"]]
        else:
            low_data_onlyif = low_data["onlyif"]
        for entry in low_data_onlyif:
            cmd = self.functions["cmd.retcode"](
                entry, ignore_retcode=True, python_shell=True, **cmd_opts
            )
            log.debug("Last command return code: {0}".format(cmd))
            if cmd != 0 and ret["result"] is False:
                ret.update(
                    {
                        "comment": "onlyif execution failed",
                        "skip_watch": True,
                        "result": True,
                    }
                )
                return ret
            elif cmd == 0:
                ret.update({"comment": "onlyif execution succeeded", "result": False})
        return ret

    if "unless" in low_data:
        if not isinstance(low_data["unless"], list):
            low_data_unless = [low_data["unless"]]
        else:
            low_data_unless = low_data["unless"]
        for entry in low_data_unless:
            cmd = self.functions["cmd.retcode"](
                entry, ignore_retcode=True, python_shell=True, **cmd_opts
            )
            log.debug("Last command return code: {0}".format(cmd))
            if cmd == 0 and ret["result"] is False:
                ret.update(
                    {
                        "comment": "unless execution succeeded",
                        "skip_watch": True,
                        "result": True,
                    }
                )
            elif cmd != 0:
                ret.update({"comment": "unless execution failed", "result": False})
                return ret

    # No reason to stop, return ret
    return ret


# Traceback (RuntimeError)
[ERROR   ] JSON Render failed for:
Traceback (most recent call last):
File "/tmp/.ubuntu_1804ae_salt/salt-call", line 15, in <module>
salt_call()
File "/tmp/.ubuntu_1804ae_salt/py2/salt/scripts.py", line 333, in salt_call
client.run()
File "/tmp/.ubuntu_1804ae_salt/py2/salt/cli/call.py", line 58, in run
caller.run()
File "/tmp/.ubuntu_1804ae_salt/py2/salt/cli/caller.py", line 133, in run
ret = self.call()
File "/tmp/.ubuntu_1804ae_salt/py2/salt/cli/caller.py", line 196, in call
ret['return'] = func(*args, **kwargs)
File "/tmp/.ubuntu_1804ae_salt/py2/salt/modules/state.py", line 1456, in pkg
ret = st_.call_chunks(lowstate)
File "/tmp/.ubuntu_1804ae_salt/py2/salt/state.py", line 1769, in call_chunks
running = self.call_chunk(low, running, chunks)
File "/tmp/.ubuntu_1804ae_salt/py2/salt/state.py", line 2030, in call_chunk
running = self.call_chunk(chunk, running, chunks)
File "/tmp/.ubuntu_1804ae_salt/py2/salt/state.py", line 2041, in call_chunk
running = self.call_chunk(low, running, chunks)
File "/tmp/.ubuntu_1804ae_salt/py2/salt/state.py", line 2041, in call_chunk
running = self.call_chunk(low, running, chunks)

...

File "/tmp/.ubuntu_1804ae_salt/py2/salt/state.py", line 2041, in call_chunk
running = self.call_chunk(low, running, chunks)
File "/tmp/.ubuntu_1804ae_salt/py2/salt/state.py", line 2041, in call_chunk
running = self.call_chunk(low, running, chunks)
File "/tmp/.ubuntu_1804ae_salt/py2/salt/state.py", line 1938, in call_chunk
low = self._mod_aggregate(low, running, chunks)
File "/tmp/.ubuntu_1804ae_salt/py2/salt/state.py", line 735, in _mod_aggregate
agg_opt = self.functions['config.option']('state_aggregate')
File "/tmp/.ubuntu_1804ae_salt/py2/salt/loader.py", line 1052, in __getitem__
func = super(LazyLoader, self).__getitem__(item)
File "/tmp/.ubuntu_1804ae_salt/py2/salt/utils/lazy.py", line 83, in __getitem__
if self._missing(key):
RuntimeError: maximum recursion depth exceeded
[ERROR   ] No JSON object could be decoded

# Fixed code
def _run_check(self, low_data):
    """
    Check that unless doesn't return 0, and that onlyif returns a 0.
    """
    ret = {"result": False}
    cmd_opts = {}

    if "shell" in self.opts["grains"]:
        cmd_opts["shell"] = self.opts["grains"].get("shell")
    if "onlyif" in low_data:
        if not isinstance(low_data["onlyif"], list):
            low_data_onlyif = [low_data["onlyif"]]
        else:
            low_data_onlyif = low_data["onlyif"]
        for entry in low_data_onlyif:
            if not isinstance(entry, string_types):
                ret.update(
                    {
                        "comment": "onlyif execution failed, bad type passed",
                        "result": False,
                    }
                )
                return ret
            cmd = self.functions["cmd.retcode"](
                entry, ignore_retcode=True, python_shell=True, **cmd_opts
            )
            log.debug("Last command return code: {0}".format(cmd))
            if cmd != 0 and ret["result"] is False:
                ret.update(
                    {
                        "comment": "onlyif execution failed",
                        "skip_watch": True,
                        "result": True,
                    }
                )
                return ret
            elif cmd == 0:
                ret.update({"comment": "onlyif execution succeeded", "result": False})
        return ret

    if "unless" in low_data:
        if not isinstance(low_data["unless"], list):
            low_data_unless = [low_data["unless"]]
        else:
            low_data_unless = low_data["unless"]
        for entry in low_data_unless:
            if not isinstance(entry, string_types):
                ret.update(
                    {
                        "comment": "unless execution failed, bad type passed",
                        "result": False,
                    }
                )
                return ret
            cmd = self.functions["cmd.retcode"](
                entry, ignore_retcode=True, python_shell=True, **cmd_opts
            )
            log.debug("Last command return code: {0}".format(cmd))
            if cmd == 0 and ret["result"] is False:
                ret.update(
                    {
                        "comment": "unless execution succeeded",
                        "skip_watch": True,
                        "result": True,
                    }
                )
            elif cmd != 0:
                ret.update({"comment": "unless execution failed", "result": False})
                return ret

    # No reason to stop, return ret
    return ret