# Buggy code
def runner(opts):
    """
    Directly call a function inside a loader directory
    """
    return LazyLoader(
        _module_dirs(opts, "runners", "runner", ext_type_dirs="runner_dirs"),
        opts,
        tag="runners",
        pack={"__salt__": minion_mods(opts)},
    )


# Traceback (KeyError)
[TRACE   ] 'semanage' could not be found in the following search path: ['/srv/mastersalt/makina-states/bin', '/srv/salt/makina-states/bin', '/usr/local/sbin', '/srv/salt/makina-states/bin', '/usr/local/bin', '/srv/salt/makina-states/bin', '/usr/sbin', '/usr/bin', '/sbin', '/bin', '/usr/games', '/usr/local/games']
[DEBUG   ] KeyError when loading groupadd
Traceback (most recent call last):
File "/srv/mastersalt/makina-states/src/salt/salt/loader.py", line 1142, in process_virtual
virtual = mod.__virtual__()
File "/srv/mastersalt/makina-states/src/salt/salt/modules/groupadd.py", line 21, in __virtual__
if __grains__['kernel'] in ('Linux', 'OpenBSD', 'NetBSD'):
KeyError: 'kernel'
[TRACE   ] 'varnishd' could not be found in the following search path: ['/srv/mastersalt/makina-states/bin', '/srv/salt/makina-states/bin', '/usr/local/sbin', '/srv/salt/makina-states/bin', '/usr/local/bin', '/srv/salt/makina-states/bin', '/usr/sbin', '/usr/bin', '/sbin', '/bin', '/usr/games', '/usr/local/games']
[DEBUG   ] KeyError when loading xapi
Traceback (most recent call last):
File "/srv/mastersalt/makina-states/src/salt/salt/loader.py", line 1142, in process_virtual
virtual = mod.__virtual__()
File "/srv/mastersalt/makina-states/src/salt/salt/modules/xapi.py", line 68, in __virtual__
if _check_xenapi() is not False:
File "/srv/mastersalt/makina-states/src/salt/salt/modules/xapi.py", line 50, in _check_xenapi
if __grains__['os'] == 'Debian':
KeyError: 'os'
[DEBUG   ] KeyError when loading netbsd_sysctl
Traceback (most recent call last):
File "/srv/mastersalt/makina-states/src/salt/salt/loader.py", line 1142, in process_virtual
virtual = mod.__virtual__()
File "/srv/mastersalt/makina-states/src/salt/salt/modules/netbsd_sysctl.py", line 21, in __virtual__
return __virtualname__ if __grains__['os'] == 'NetBSD' else False
KeyError: 'os'
[TRACE   ] 'rabbitmqctl' could not be found in the following search path: ['/srv/mastersalt/makina-states/bin', '/srv/salt/makina-states/bin', '/usr/local/sbin', '/srv/salt/makina-states/bin', '/usr/local/bin', '/srv/salt/makina-states/bin', '/usr/sbin', '/usr/bin', '/sbin', '/bin', '/usr/games', '/usr/local/games']
[TRACE   ] Loaded parted as virtual partition
[TRACE   ] 'gluster' could not be found in the following search path: ['/srv/mastersalt/makina-states/bin', '/srv/salt/makina-states/bin', '/usr/local/sbin', '/srv/salt/makina-states/bin', '/usr/local/bin', '/srv/salt/makina-states/bin', '/usr/sbin', '/usr/bin', '/sbin', '/bin', '/usr/games', '/usr/local/games']
[DEBUG   ] KeyError when loading solarisips
Traceback (most recent call last):
File "/srv/mastersalt/makina-states/src/salt/salt/loader.py", line 1142, in process_virtual
virtual = mod.__virtual__()
File "/srv/mastersalt/makina-states/src/salt/salt/modules/solarisips.py", line 40, in __virtual__
if __grains__['os'] == 'Solaris' and __grains__['kernelrelease'] == '5.11':
KeyError: 'os'
[DEBUG   ] KeyError when loading pw_group
Traceback (most recent call last):
File "/srv/mastersalt/makina-states/src/salt/salt/loader.py", line 1142, in process_virtual
virtual = mod.__virtual__()
File "/srv/mastersalt/makina-states/src/salt/salt/modules/pw_group.py", line 30, in __virtual__
return __virtualname__ if __grains__['kernel'] == 'FreeBSD' else False
KeyError: 'kernel'
[DEBUG   ] KeyError when loading apache
Traceback (most recent call last):
File "/srv/mastersalt/makina-states/src/salt/salt/loader.py", line 1142, in process_virtual
virtual = mod.__virtual__()
File "/srv/mastersalt/makina-states/src/salt/salt/modules/apache.py", line 41, in __virtual__
cmd = _detect_os()
File "/srv/mastersalt/makina-states/src/salt/salt/modules/apache.py", line 52, in _detect_os
if __grains__['os_family'] == 'RedHat':
KeyError: 'os_family'
[DEBUG   ] KeyError when loading chocolatey

# Fixed code
def runner(opts):
    """
    Directly call a function inside a loader directory
    """
    ret = LazyLoader(
        _module_dirs(opts, "runners", "runner", ext_type_dirs="runner_dirs"),
        opts,
        tag="runners",
    )
    # TODO: change from __salt__ to something else, we overload __salt__ too much
    ret.pack["__salt__"] = ret
    return ret