# Buggy code
def main():
    module = AnsibleModule(
        argument_spec=dict(
            state=dict(
                type="str",
                default="installed",
                choices=["absent", "installed", "present", "removed"],
            ),
            update_cache=dict(type="bool", default=False, aliases=["update-cache"]),
            force=dict(type="bool", default=True),
            no_recommends=dict(type="bool", default=True, aliases=["no-recommends"]),
            name=dict(type="list", required=True, aliases=["package", "pkg"]),
            root=dict(type="str", aliases=["installroot"]),
        ),
    )

    p = module.params

    force_yes = p["force"]
    no_recommends_yes = p["no_recommends"]
    root = p["root"]

    if p["update_cache"]:
        update_package_db(module)

    packages = p["package"]

    if p["state"] in ["installed", "present"]:
        install_packages(module, packages, root, force_yes, no_recommends_yes)

    elif p["state"] in ["removed", "absent"]:
        remove_packages(module, packages, root)


# Traceback (KeyError)
ansible-playbook -vvvv test.yml
ansible-playbook 2.7.0
config file = /users/bruno/.ansible.cfg
configured module search path = [u'/users/bruno/.ansible/plugins/modules', u'/usr/share/ansible/plugins/modules']
ansible python module location = /usr/lib/python2.7/site-packages/ansible
executable location = /usr/bin/ansible-playbook
python version = 2.7.15 (default, Jun 17 2018, 18:39:32) [GCC 7.3.0]
Using /users/bruno/.ansible.cfg as config file
setting up inventory plugins
Parsed /etc/ansible/hosts inventory source with ini plugin
[WARNING]: provided hosts list is empty, only localhost is available. Note that the implicit localhost does not match 'all'

Loading callback plugin default of type stdout, v2.0 from /usr/lib/python2.7/site-packages/ansible/plugins/callback/default.pyc

PLAYBOOK: test.yml ***********************************************************************************************************************************************************************************************************************************
1 plays in test.yml

PLAY [localhost] *************************************************************************************************************************************************************************************************************************************

TASK [Gathering Facts] *******************************************************************************************************************************************************************************************************************************
task path: /users/bruno/prj/mageia/docker/test.yml:2
Using module file /usr/lib/python2.7/site-packages/ansible/modules/system/setup.py
<127.0.0.1> ESTABLISH LOCAL CONNECTION FOR USER: bruno
<127.0.0.1> EXEC /bin/sh -c 'sudo -H -S -n -u root /bin/sh -c '"'"'echo BECOME-SUCCESS-ylusxatunijpxvaudmhxohfqachblelm; /usr/bin/python2'"'"' &amp;&amp; sleep 0'
ok: [localhost]
META: ran handlers

TASK [Check that mon is installed] *******************************************************************************************************************************************************************************************************************
task path: /users/bruno/prj/mageia/docker/test.yml:4
Using module file /usr/lib/python2.7/site-packages/ansible/modules/packaging/os/urpmi.py
<127.0.0.1> ESTABLISH LOCAL CONNECTION FOR USER: bruno
<127.0.0.1> EXEC /bin/sh -c 'sudo -H -S -n -u root /bin/sh -c '"'"'echo BECOME-SUCCESS-yxixemcphofqstjjjdoocwwrepebhudb; /usr/bin/python2'"'"' &amp;&amp; sleep 0'
The full traceback is:
Traceback (most recent call last):
File "<stdin>", line 113, in <module>
File "<stdin>", line 105, in _ansiballz_main
File "<stdin>", line 48, in invoke_module
File "/tmp/ansible_urpmi_payload_GtD0Gf/__main__.py", line 228, in <module>
File "/tmp/ansible_urpmi_payload_GtD0Gf/__main__.py", line 218, in main
KeyError: 'package'

fatal: [localhost]: FAILED! => {
"changed": false,
"module_stderr": "Traceback (most recent call last):\n  File \"<stdin>\", line 113, in <module>\n  File \"<stdin>\", line 105, in _ansiballz_main\n  File \"<stdin>\", line 48, in invoke_module\n  File \"/tmp/ansible_urpmi_payload_GtD0Gf/__main__.py\", line 228, in <module>\n  File \"/tmp/ansible_urpmi_payload_GtD0Gf/__main__.py\", line 218, in main\nKeyError: 'package'\n",
"module_stdout": "",
"msg": "MODULE FAILURE\nSee stdout/stderr for the exact error",
"rc": 1
}
to retry, use: --limit @/users/bruno/prj/mageia/docker/test.retry

PLAY RECAP *******************************************************************************************************************************************************************************************************************************************
localhost                  : ok=1    changed=0    unreachable=0    failed=1

# Fixed code
def main():
    module = AnsibleModule(
        argument_spec=dict(
            state=dict(
                type="str",
                default="installed",
                choices=["absent", "installed", "present", "removed"],
            ),
            update_cache=dict(type="bool", default=False, aliases=["update-cache"]),
            force=dict(type="bool", default=True),
            no_recommends=dict(type="bool", default=True, aliases=["no-recommends"]),
            name=dict(type="list", required=True, aliases=["package", "pkg"]),
            root=dict(type="str", aliases=["installroot"]),
        ),
    )

    p = module.params

    if p["update_cache"]:
        update_package_db(module)

    if p["state"] in ["installed", "present"]:
        install_packages(module, p["name"], p["root"], p["force"], p["no_recommends"])

    elif p["state"] in ["removed", "absent"]:
        remove_packages(module, p["name"], p["root"])