# Buggy code
def requisite_in(self, high):
    """
    Extend the data reference with requisite_in arguments
    """
    req_in = set(
        [
            "require_in",
            "watch_in",
            "onfail_in",
            "onchanges_in",
            "use",
            "use_in",
            "prereq",
            "prereq_in",
        ]
    )
    req_in_all = req_in.union(
        set(
            [
                "require",
                "watch",
                "onfail",
                "onfail_stop",
                "onchanges",
            ]
        )
    )
    extend = {}
    errors = []
    for id_, body in six.iteritems(high):
        if not isinstance(body, dict):
            continue
        for state, run in six.iteritems(body):
            if state.startswith("__"):
                continue
            for arg in run:
                if isinstance(arg, dict):
                    # It is not a function, verify that the arg is a
                    # requisite in statement
                    if len(arg) < 1:
                        # Empty arg dict
                        # How did we get this far?
                        continue
                    # Split out the components
                    key = next(iter(arg))
                    if key not in req_in:
                        continue
                    rkey = key.split("_")[0]
                    items = arg[key]
                    if isinstance(items, dict):
                        # Formatted as a single req_in
                        for _state, name in six.iteritems(items):
                            # Not a use requisite_in
                            found = False
                            if name not in extend:
                                extend[name] = OrderedDict()
                            if "." in _state:
                                errors.append(
                                    "Invalid requisite in {0}: {1} for "
                                    "{2}, in SLS '{3}'. Requisites must "
                                    "not contain dots, did you mean '{4}'?".format(
                                        rkey,
                                        _state,
                                        name,
                                        body["__sls__"],
                                        _state[: _state.find(".")],
                                    )
                                )
                                _state = _state.split(".")[0]
                            if _state not in extend[name]:
                                extend[name][_state] = []
                            extend[name]["__env__"] = body["__env__"]
                            extend[name]["__sls__"] = body["__sls__"]
                            for ind in range(len(extend[name][_state])):
                                if next(iter(extend[name][_state][ind])) == rkey:
                                    # Extending again
                                    extend[name][_state][ind][rkey].append({state: id_})
                                    found = True
                            if found:
                                continue
                            # The rkey is not present yet, create it
                            extend[name][_state].append({rkey: [{state: id_}]})

                    if isinstance(items, list):
                        # Formed as a list of requisite additions
                        hinges = []
                        for ind in items:
                            if not isinstance(ind, dict):
                                # Malformed req_in
                                continue
                            if len(ind) < 1:
                                continue
                            pstate = next(iter(ind))
                            pname = ind[pstate]
                            if pstate == "sls":
                                # Expand hinges here
                                hinges = find_sls_ids(pname, high)
                            else:
                                hinges.append((pname, pstate))
                            if "." in pstate:
                                errors.append(
                                    "Invalid requisite in {0}: {1} for "
                                    "{2}, in SLS '{3}'. Requisites must "
                                    "not contain dots, did you mean '{4}'?".format(
                                        rkey,
                                        pstate,
                                        pname,
                                        body["__sls__"],
                                        pstate[: pstate.find(".")],
                                    )
                                )
                                pstate = pstate.split(".")[0]
                            for tup in hinges:
                                name, _state = tup
                                if key == "prereq_in":
                                    # Add prerequired to origin
                                    if id_ not in extend:
                                        extend[id_] = OrderedDict()
                                    if state not in extend[id_]:
                                        extend[id_][state] = []
                                    extend[id_][state].append(
                                        {"prerequired": [{_state: name}]}
                                    )
                                if key == "prereq":
                                    # Add prerequired to prereqs
                                    ext_ids = find_name(name, _state, high)
                                    for ext_id, _req_state in ext_ids:
                                        if ext_id not in extend:
                                            extend[ext_id] = OrderedDict()
                                        if _req_state not in extend[ext_id]:
                                            extend[ext_id][_req_state] = []
                                        extend[ext_id][_req_state].append(
                                            {"prerequired": [{state: id_}]}
                                        )
                                    continue
                                if key == "use_in":
                                    # Add the running states args to the
                                    # use_in states
                                    ext_ids = find_name(name, _state, high)
                                    for ext_id, _req_state in ext_ids:
                                        if not ext_id:
                                            continue
                                        ext_args = state_args(ext_id, _state, high)
                                        if ext_id not in extend:
                                            extend[ext_id] = OrderedDict()
                                        if _req_state not in extend[ext_id]:
                                            extend[ext_id][_req_state] = []
                                        ignore_args = req_in_all.union(ext_args)
                                        for arg in high[id_][state]:
                                            if not isinstance(arg, dict):
                                                continue
                                            if len(arg) != 1:
                                                continue
                                            if next(iter(arg)) in ignore_args:
                                                continue
                                            # Don't use name or names
                                            if next(six.iterkeys(arg)) == "name":
                                                continue
                                            if next(six.iterkeys(arg)) == "names":
                                                continue
                                            extend[ext_id][_req_state].append(arg)
                                    continue
                                if key == "use":
                                    # Add the use state's args to the
                                    # running state
                                    ext_ids = find_name(name, _state, high)
                                    for ext_id, _req_state in ext_ids:
                                        if not ext_id:
                                            continue
                                        loc_args = state_args(id_, state, high)
                                        if id_ not in extend:
                                            extend[id_] = OrderedDict()
                                        if state not in extend[id_]:
                                            extend[id_][state] = []
                                        ignore_args = req_in_all.union(loc_args)
                                        for arg in high[ext_id][_req_state]:
                                            if not isinstance(arg, dict):
                                                continue
                                            if len(arg) != 1:
                                                continue
                                            if next(iter(arg)) in ignore_args:
                                                continue
                                            # Don't use name or names
                                            if next(six.iterkeys(arg)) == "name":
                                                continue
                                            if next(six.iterkeys(arg)) == "names":
                                                continue
                                            extend[id_][state].append(arg)
                                    continue
                                found = False
                                if name not in extend:
                                    extend[name] = OrderedDict()
                                if _state not in extend[name]:
                                    extend[name][_state] = []
                                extend[name]["__env__"] = body["__env__"]
                                extend[name]["__sls__"] = body["__sls__"]
                                for ind in range(len(extend[name][_state])):
                                    if next(iter(extend[name][_state][ind])) == rkey:
                                        # Extending again
                                        extend[name][_state][ind][rkey].append(
                                            {state: id_}
                                        )
                                        found = True
                                if found:
                                    continue
                                # The rkey is not present yet, create it
                                extend[name][_state].append({rkey: [{state: id_}]})
    high["__extend__"] = []
    for key, val in six.iteritems(extend):
        high["__extend__"].append({key: val})
    req_in_high, req_in_errors = self.reconcile_extend(high)
    errors.extend(req_in_errors)
    return req_in_high, errors


# Traceback (RuntimeError)
[DEBUG   ] Reading configuration from /etc/salt/minion
[DEBUG   ] Using cached minion ID from /etc/salt/minion_id: master.localhost
[DEBUG   ] Configuration file path: /etc/salt/minion
[WARNING ] Insecure logging configuration detected! Sensitive data may be logged.
[DEBUG   ] Reading configuration from /etc/salt/minion
[DEBUG   ] Determining pillar cache
[DEBUG   ] LazyLoaded jinja.render
[DEBUG   ] LazyLoaded yaml.render
[DEBUG   ] LazyLoaded jinja.render
[DEBUG   ] LazyLoaded yaml.render
[DEBUG   ] LazyLoaded state.apply
[DEBUG   ] LazyLoaded saltutil.is_running
[DEBUG   ] LazyLoaded grains.get
[DEBUG   ] LazyLoaded roots.envs
[DEBUG   ] Could not LazyLoad roots.init: 'roots.init' is not available.
[DEBUG   ] Updating roots fileserver cache
[INFO    ] Loading fresh modules for state activity
[DEBUG   ] LazyLoaded jinja.render
[DEBUG   ] LazyLoaded yaml.render
[DEBUG   ] Could not find file 'salt://recursion_error.sls' in saltenv 'base'
[DEBUG   ] In saltenv 'base', looking at rel_path 'recursion_error/init.sls' to resolve 'salt://recursion_error/init.sls'
[DEBUG   ] In saltenv 'base', ** considering ** path '/var/cache/salt/minion/files/base/recursion_error/init.sls' to resolve 'salt://recursion_error/init.sls'
[DEBUG   ] compile template: /var/cache/salt/minion/files/base/recursion_error/init.sls
[DEBUG   ] Jinja search path: ['/var/cache/salt/minion/files/base']
[PROFILE ] Time (in seconds) to render '/var/cache/salt/minion/files/base/recursion_error/init.sls' using 'jinja' renderer: 0.00553703308105
[DEBUG   ] Rendered data from file: /var/cache/salt/minion/files/base/recursion_error/init.sls:
item1:
cmd.run:
- name: cat /tmp/content
- unless: test -e /tmp/content

item2:
file.managed:
- name: /tmp/content
- contents: 'hi'
- prereq:
- item1

[DEBUG   ] LazyLoaded config.get
[DEBUG   ] Results of YAML rendering:
OrderedDict([('item1', OrderedDict([('cmd.run', [OrderedDict([('name', 'cat /tmp/content')]), OrderedDict([('unless', 'test -e /tmp/content')])])])), ('item2', OrderedDict([('file.managed', [OrderedDict([('name', '/tmp/content')]), OrderedDict([('contents', 'hi')]), OrderedDict([('prereq', ['item1'])])])]))])
[PROFILE ] Time (in seconds) to render '/var/cache/salt/minion/files/base/recursion_error/init.sls' using 'yaml' renderer: 0.00709915161133
[DEBUG   ] LazyLoaded cmd.run
[INFO    ] Running state [cat /tmp/content] at time 19:17:11.617011
[INFO    ] Executing state cmd.run for [cat /tmp/content]
[DEBUG   ] LazyLoaded cmd.retcode
[INFO    ] Executing command 'test -e /tmp/content' in directory '/root'
[DEBUG   ] output:
[DEBUG   ] Last command return code: 1
[INFO    ] Command "cat /tmp/content" would have been executed
[INFO    ] Completed state [cat /tmp/content] at time 19:17:11.637571 duration_in_ms=20.559
[DEBUG   ] LazyLoaded file.managed
[ERROR   ] An un-handled exception was caught by salt's global exception handler:
RuntimeError: maximum recursion depth exceeded
Traceback (most recent call last):
File "/bin/salt-call", line 11, in <module>
salt_call()
File "/usr/lib/python2.7/site-packages/salt/scripts.py", line 391, in salt_call
client.run()
File "/usr/lib/python2.7/site-packages/salt/cli/call.py", line 58, in run
caller.run()
File "/usr/lib/python2.7/site-packages/salt/cli/caller.py", line 134, in run
ret = self.call()
File "/usr/lib/python2.7/site-packages/salt/cli/caller.py", line 204, in call
ret['return'] = func(*args, **kwargs)
File "/usr/lib/python2.7/site-packages/salt/modules/state.py", line 592, in apply_
return sls(mods, **kwargs)
File "/usr/lib/python2.7/site-packages/salt/modules/state.py", line 1109, in sls
ret = st_.state.call_high(high_, orchestration_jid)
File "/usr/lib/python2.7/site-packages/salt/state.py", line 2531, in call_high
ret = self.call_chunks(chunks)
File "/usr/lib/python2.7/site-packages/salt/state.py", line 2017, in call_chunks
running = self.call_chunk(low, running, chunks)
File "/usr/lib/python2.7/site-packages/salt/state.py", line 2356, in call_chunk
running = self.call_chunk(low, running, chunks)
File "/usr/lib/python2.7/site-packages/salt/state.py", line 2356, in call_chunk
running = self.call_chunk(low, running, chunks)
File "/usr/lib/python2.7/site-packages/salt/state.py", line 2356, in call_chunk
running = self.call_chunk(low, running, chunks)
File "/usr/lib/python2.7/site-packages/salt/state.py", line 2356, in call_chunk
running = self.call_chunk(low, running, chunks)
File "/usr/lib/python2.7/site-packages/salt/state.py", line 2356, in call_chunk
running = self.call_chunk(low, running, chunks)
[...]
File "/usr/lib/python2.7/site-packages/salt/state.py", line 2356, in call_chunk
running = self.call_chunk(low, running, chunks)
File "/usr/lib/python2.7/site-packages/salt/state.py", line 2356, in call_chunk
running = self.call_chunk(low, running, chunks)
File "/usr/lib/python2.7/site-packages/salt/state.py", line 2356, in call_chunk
running = self.call_chunk(low, running, chunks)
File "/usr/lib/python2.7/site-packages/salt/state.py", line 2356, in call_chunk
running = self.call_chunk(low, running, chunks)
File "/usr/lib/python2.7/site-packages/salt/state.py", line 2356, in call_chunk
running = self.call_chunk(low, running, chunks)
File "/usr/lib/python2.7/site-packages/salt/state.py", line 2356, in call_chunk
running = self.call_chunk(low, running, chunks)
File "/usr/lib/python2.7/site-packages/salt/state.py", line 2356, in call_chunk
running = self.call_chunk(low, running, chunks)
File "/usr/lib/python2.7/site-packages/salt/state.py", line 2356, in call_chunk
running = self.call_chunk(low, running, chunks)
File "/usr/lib/python2.7/site-packages/salt/state.py", line 2356, in call_chunk
running = self.call_chunk(low, running, chunks)
File "/usr/lib/python2.7/site-packages/salt/state.py", line 2356, in call_chunk
running = self.call_chunk(low, running, chunks)
File "/usr/lib/python2.7/site-packages/salt/state.py", line 2356, in call_chunk
running = self.call_chunk(low, running, chunks)
File "/usr/lib/python2.7/site-packages/salt/state.py", line 2249, in call_chunk
low = self._mod_aggregate(low, running, chunks)
File "/usr/lib/python2.7/site-packages/salt/state.py", line 769, in _mod_aggregate
agg_opt = self.functions['config.option']('state_aggregate')
File "/usr/lib/python2.7/site-packages/salt/loader.py", line 1114, in __getitem__
func = super(LazyLoader, self).__getitem__(item)
File "/usr/lib/python2.7/site-packages/salt/utils/lazy.py", line 91, in __getitem__
if self._missing(key):
RuntimeError: maximum recursion depth exceeded

# Fixed code
def requisite_in(self, high):
    """
    Extend the data reference with requisite_in arguments
    """
    req_in = set(
        [
            "require_in",
            "watch_in",
            "onfail_in",
            "onchanges_in",
            "use",
            "use_in",
            "prereq",
            "prereq_in",
        ]
    )
    req_in_all = req_in.union(
        set(
            [
                "require",
                "watch",
                "onfail",
                "onfail_stop",
                "onchanges",
            ]
        )
    )
    extend = {}
    errors = []
    for id_, body in six.iteritems(high):
        if not isinstance(body, dict):
            continue
        for state, run in six.iteritems(body):
            if state.startswith("__"):
                continue
            for arg in run:
                if isinstance(arg, dict):
                    # It is not a function, verify that the arg is a
                    # requisite in statement
                    if len(arg) < 1:
                        # Empty arg dict
                        # How did we get this far?
                        continue
                    # Split out the components
                    key = next(iter(arg))
                    if key not in req_in:
                        continue
                    rkey = key.split("_")[0]
                    items = arg[key]
                    if isinstance(items, dict):
                        # Formatted as a single req_in
                        for _state, name in six.iteritems(items):
                            # Not a use requisite_in
                            found = False
                            if name not in extend:
                                extend[name] = OrderedDict()
                            if "." in _state:
                                errors.append(
                                    "Invalid requisite in {0}: {1} for "
                                    "{2}, in SLS '{3}'. Requisites must "
                                    "not contain dots, did you mean '{4}'?".format(
                                        rkey,
                                        _state,
                                        name,
                                        body["__sls__"],
                                        _state[: _state.find(".")],
                                    )
                                )
                                _state = _state.split(".")[0]
                            if _state not in extend[name]:
                                extend[name][_state] = []
                            extend[name]["__env__"] = body["__env__"]
                            extend[name]["__sls__"] = body["__sls__"]
                            for ind in range(len(extend[name][_state])):
                                if next(iter(extend[name][_state][ind])) == rkey:
                                    # Extending again
                                    extend[name][_state][ind][rkey].append({state: id_})
                                    found = True
                            if found:
                                continue
                            # The rkey is not present yet, create it
                            extend[name][_state].append({rkey: [{state: id_}]})

                    if isinstance(items, list):
                        # Formed as a list of requisite additions
                        hinges = []
                        for ind in items:
                            if not isinstance(ind, dict):
                                # Malformed req_in
                                if ind in high:
                                    _ind_high = [
                                        x for x in high[ind] if not x.startswith("__")
                                    ]
                                    ind = {_ind_high[0]: ind}
                                else:
                                    found = False
                                    for _id in iter(high):
                                        for state in [
                                            state
                                            for state in iter(high[_id])
                                            if not state.startswith("__")
                                        ]:
                                            for j in iter(high[_id][state]):
                                                if isinstance(j, dict) and "name" in j:
                                                    if j["name"] == ind:
                                                        ind = {state: _id}
                                                        found = True
                                    if not found:
                                        continue
                            if len(ind) < 1:
                                continue
                            pstate = next(iter(ind))
                            pname = ind[pstate]
                            if pstate == "sls":
                                # Expand hinges here
                                hinges = find_sls_ids(pname, high)
                            else:
                                hinges.append((pname, pstate))
                            if "." in pstate:
                                errors.append(
                                    "Invalid requisite in {0}: {1} for "
                                    "{2}, in SLS '{3}'. Requisites must "
                                    "not contain dots, did you mean '{4}'?".format(
                                        rkey,
                                        pstate,
                                        pname,
                                        body["__sls__"],
                                        pstate[: pstate.find(".")],
                                    )
                                )
                                pstate = pstate.split(".")[0]
                            for tup in hinges:
                                name, _state = tup
                                if key == "prereq_in":
                                    # Add prerequired to origin
                                    if id_ not in extend:
                                        extend[id_] = OrderedDict()
                                    if state not in extend[id_]:
                                        extend[id_][state] = []
                                    extend[id_][state].append(
                                        {"prerequired": [{_state: name}]}
                                    )
                                if key == "prereq":
                                    # Add prerequired to prereqs
                                    ext_ids = find_name(name, _state, high)
                                    for ext_id, _req_state in ext_ids:
                                        if ext_id not in extend:
                                            extend[ext_id] = OrderedDict()
                                        if _req_state not in extend[ext_id]:
                                            extend[ext_id][_req_state] = []
                                        extend[ext_id][_req_state].append(
                                            {"prerequired": [{state: id_}]}
                                        )
                                    continue
                                if key == "use_in":
                                    # Add the running states args to the
                                    # use_in states
                                    ext_ids = find_name(name, _state, high)
                                    for ext_id, _req_state in ext_ids:
                                        if not ext_id:
                                            continue
                                        ext_args = state_args(ext_id, _state, high)
                                        if ext_id not in extend:
                                            extend[ext_id] = OrderedDict()
                                        if _req_state not in extend[ext_id]:
                                            extend[ext_id][_req_state] = []
                                        ignore_args = req_in_all.union(ext_args)
                                        for arg in high[id_][state]:
                                            if not isinstance(arg, dict):
                                                continue
                                            if len(arg) != 1:
                                                continue
                                            if next(iter(arg)) in ignore_args:
                                                continue
                                            # Don't use name or names
                                            if next(six.iterkeys(arg)) == "name":
                                                continue
                                            if next(six.iterkeys(arg)) == "names":
                                                continue
                                            extend[ext_id][_req_state].append(arg)
                                    continue
                                if key == "use":
                                    # Add the use state's args to the
                                    # running state
                                    ext_ids = find_name(name, _state, high)
                                    for ext_id, _req_state in ext_ids:
                                        if not ext_id:
                                            continue
                                        loc_args = state_args(id_, state, high)
                                        if id_ not in extend:
                                            extend[id_] = OrderedDict()
                                        if state not in extend[id_]:
                                            extend[id_][state] = []
                                        ignore_args = req_in_all.union(loc_args)
                                        for arg in high[ext_id][_req_state]:
                                            if not isinstance(arg, dict):
                                                continue
                                            if len(arg) != 1:
                                                continue
                                            if next(iter(arg)) in ignore_args:
                                                continue
                                            # Don't use name or names
                                            if next(six.iterkeys(arg)) == "name":
                                                continue
                                            if next(six.iterkeys(arg)) == "names":
                                                continue
                                            extend[id_][state].append(arg)
                                    continue
                                found = False
                                if name not in extend:
                                    extend[name] = OrderedDict()
                                if _state not in extend[name]:
                                    extend[name][_state] = []
                                extend[name]["__env__"] = body["__env__"]
                                extend[name]["__sls__"] = body["__sls__"]
                                for ind in range(len(extend[name][_state])):
                                    if next(iter(extend[name][_state][ind])) == rkey:
                                        # Extending again
                                        extend[name][_state][ind][rkey].append(
                                            {state: id_}
                                        )
                                        found = True
                                if found:
                                    continue
                                # The rkey is not present yet, create it
                                extend[name][_state].append({rkey: [{state: id_}]})
    high["__extend__"] = []
    for key, val in six.iteritems(extend):
        high["__extend__"].append({key: val})
    req_in_high, req_in_errors = self.reconcile_extend(high)
    errors.extend(req_in_errors)
    return req_in_high, errors