# Buggy code
def main():
    # the command module is the one ansible module that does not take key=value args
    # hence don't copy this one if you are looking to build others!
    module = AnsibleModule(
        argument_spec=dict(
            _raw_params=dict(),
            _uses_shell=dict(type="bool", default=False),
            argv=dict(type="list"),
            chdir=dict(type="path"),
            executable=dict(),
            creates=dict(type="path"),
            removes=dict(type="path"),
            # The default for this really comes from the action plugin
            warn=dict(type="bool", default=True),
            stdin=dict(required=False),
        ),
        supports_check_mode=True,
    )
    shell = module.params["_uses_shell"]
    chdir = module.params["chdir"]
    executable = module.params["executable"]
    args = module.params["_raw_params"]
    argv = module.params["argv"]
    creates = module.params["creates"]
    removes = module.params["removes"]
    warn = module.params["warn"]
    stdin = module.params["stdin"]

    if not shell and executable:
        module.warn(
            "As of Ansible 2.4, the parameter 'executable' is no longer supported with the 'command' module. Not using '%s'."
            % executable
        )
        executable = None

    if (not args or args.strip() == "") and not argv:
        module.fail_json(rc=256, msg="no command given")

    if args and argv:
        module.fail_json(rc=256, msg="only command or argv can be given, not both")

    if not shell and args:
        args = shlex.split(args)

    args = args or argv

    if chdir:
        chdir = os.path.abspath(chdir)
        os.chdir(chdir)

    if creates:
        # do not run the command if the line contains creates=filename
        # and the filename already exists.  This allows idempotence
        # of command executions.
        if glob.glob(creates):
            module.exit_json(
                cmd=args,
                stdout="skipped, since %s exists" % creates,
                changed=False,
                rc=0,
            )

    if removes:
        # do not run the command if the line contains removes=filename
        # and the filename does not exist.  This allows idempotence
        # of command executions.
        if not glob.glob(removes):
            module.exit_json(
                cmd=args,
                stdout="skipped, since %s does not exist" % removes,
                changed=False,
                rc=0,
            )

    if warn:
        check_command(module, args)

    startd = datetime.datetime.now()

    if not module.check_mode:
        rc, out, err = module.run_command(
            args,
            executable=executable,
            use_unsafe_shell=shell,
            encoding=None,
            data=stdin,
        )
    elif creates or removes:
        rc = 0
        out = err = b"Command would have run if not in check mode"
    else:
        module.exit_json(msg="skipped, running in check mode", skipped=True)

    endd = datetime.datetime.now()
    delta = endd - startd

    result = dict(
        cmd=args,
        stdout=out.rstrip(b"\r\n"),
        stderr=err.rstrip(b"\r\n"),
        rc=rc,
        start=str(startd),
        end=str(endd),
        delta=str(delta),
        changed=True,
    )

    if rc != 0:
        module.fail_json(msg="non-zero return code", **result)

    module.exit_json(**result)


# Traceback (nTypeError)
fatal: [host1.example.invalid]: FAILED! => {"changed": false, "module_stderr": "Shared connection to host1.example.invalid closed.\r\n", "module_stdout": "Traceback (most recent call last):\r\n  File \"/tmp/ansible_Nv59ki/ansible_module_command.py\", line 271, in <module>\r\n    main()\r\n  File \"/tmp/ansible_Nv59ki/ansible_module_command.py\", line 248, in main\r\n    rc, out, err = module.run_command(args, executable=executable, use_unsafe_shell=shell, encoding=None, data=stdin)\r\n  File \"/tmp/ansible_Nv59ki/ansible_modlib.zip/ansible/module_utils/basic.py\", line 2774, in run_command\r\n  File \"/usr/lib64/python2.7/posixpath.py\", line 293, in expandvars\r\n    if '$' not in path:\r\nTypeError: argument of type 'int' is not iterable\r\n", "msg": "MODULE FAILURE", "rc": 1}

# Fixed code
def main():
    # the command module is the one ansible module that does not take key=value args
    # hence don't copy this one if you are looking to build others!
    module = AnsibleModule(
        argument_spec=dict(
            _raw_params=dict(),
            _uses_shell=dict(type="bool", default=False),
            argv=dict(type="list"),
            chdir=dict(type="path"),
            executable=dict(),
            creates=dict(type="path"),
            removes=dict(type="path"),
            # The default for this really comes from the action plugin
            warn=dict(type="bool", default=True),
            stdin=dict(required=False),
        ),
        supports_check_mode=True,
    )
    shell = module.params["_uses_shell"]
    chdir = module.params["chdir"]
    executable = module.params["executable"]
    args = module.params["_raw_params"]
    argv = module.params["argv"]
    creates = module.params["creates"]
    removes = module.params["removes"]
    warn = module.params["warn"]
    stdin = module.params["stdin"]

    if not shell and executable:
        module.warn(
            "As of Ansible 2.4, the parameter 'executable' is no longer supported with the 'command' module. Not using '%s'."
            % executable
        )
        executable = None

    if (not args or args.strip() == "") and not argv:
        module.fail_json(rc=256, msg="no command given")

    if args and argv:
        module.fail_json(rc=256, msg="only command or argv can be given, not both")

    if not shell and args:
        args = shlex.split(args)

    args = args or argv

    # All args must be strings
    if is_iterable(args, include_strings=False):
        args = [
            to_native(arg, errors="surrogate_or_strict", nonstring="simplerepr")
            for arg in args
        ]

    if chdir:
        chdir = os.path.abspath(chdir)
        os.chdir(chdir)

    if creates:
        # do not run the command if the line contains creates=filename
        # and the filename already exists.  This allows idempotence
        # of command executions.
        if glob.glob(creates):
            module.exit_json(
                cmd=args,
                stdout="skipped, since %s exists" % creates,
                changed=False,
                rc=0,
            )

    if removes:
        # do not run the command if the line contains removes=filename
        # and the filename does not exist.  This allows idempotence
        # of command executions.
        if not glob.glob(removes):
            module.exit_json(
                cmd=args,
                stdout="skipped, since %s does not exist" % removes,
                changed=False,
                rc=0,
            )

    if warn:
        check_command(module, args)

    startd = datetime.datetime.now()

    if not module.check_mode:
        rc, out, err = module.run_command(
            args,
            executable=executable,
            use_unsafe_shell=shell,
            encoding=None,
            data=stdin,
        )
    elif creates or removes:
        rc = 0
        out = err = b"Command would have run if not in check mode"
    else:
        module.exit_json(msg="skipped, running in check mode", skipped=True)

    endd = datetime.datetime.now()
    delta = endd - startd

    result = dict(
        cmd=args,
        stdout=out.rstrip(b"\r\n"),
        stderr=err.rstrip(b"\r\n"),
        rc=rc,
        start=str(startd),
        end=str(endd),
        delta=str(delta),
        changed=True,
    )

    if rc != 0:
        module.fail_json(msg="non-zero return code", **result)

    module.exit_json(**result)