# Buggy code
def run(self, tmp=None, task_vars=None):
    if self._play_context.connection != "local":
        return dict(
            failed=True,
            msg="invalid connection specified, expected connection=local, "
            "got %s" % self._play_context.connection,
        )

    provider = self.load_provider()
    transport = provider["transport"] or "cli"

    display.vvvv(
        "connection transport is %s" % transport, self._play_context.remote_addr
    )

    if transport == "cli":
        pc = copy.deepcopy(self._play_context)
        pc.connection = "network_cli"
        pc.network_os = "ce"
        pc.remote_addr = provider["host"] or self._play_context.remote_addr
        pc.port = int(provider["port"] or self._play_context.port or 22)
        pc.remote_user = provider["username"] or self._play_context.connection_user
        pc.password = provider["password"] or self._play_context.password
        pc.timeout = int(provider["timeout"] or C.PERSISTENT_COMMAND_TIMEOUT)
        self._task.args["provider"] = provider.update(
            host=pc.remote_addr,
            port=pc.port,
            username=pc.remote_user,
            password=pc.password,
            ssh_keyfile=pc.private_key_file,
        )
        display.vvv("using connection plugin %s" % pc.connection, pc.remote_addr)
        connection = self._shared_loader_obj.connection_loader.get(
            "persistent", pc, sys.stdin
        )

        socket_path = connection.run()
        display.vvvv("socket_path: %s" % socket_path, pc.remote_addr)
        if not socket_path:
            return {
                "failed": True,
                "msg": "unable to open shell. Please see: "
                + "https://docs.ansible.com/ansible/network_debug_troubleshooting.html#unable-to-open-shell",
            }

        # make sure we are in the right cli context which should be
        # enable mode and not config module
        rc, out, err = connection.exec_command("prompt()")
        while str(out).strip().endswith("]"):
            display.vvvv(
                "wrong context, sending exit to device", self._play_context.remote_addr
            )
            connection.exec_command("return")
            rc, out, err = connection.exec_command("prompt()")

        task_vars["ansible_socket"] = socket_path

    # make sure a transport value is set in args
    self._task.args["transport"] = transport

    result = super(ActionModule, self).run(tmp, task_vars)
    return result


# Traceback (ValueError)
2017-08-08 14:54:47,105 p=31837 u=root |   31848 1502204087.10508: done running TaskExecutor() for switch1/TASK: Display Version [fa163eb3-ce3f-4ed8-a8a6-00000000001f]
2017-08-08 14:54:47,105 p=31837 u=root |   31848 1502204087.10553: sending task result for task fa163eb3-ce3f-4ed8-a8a6-00000000001f
2017-08-08 14:54:47,106 p=31837 u=root |   31848 1502204087.10610: done sending task result for task fa163eb3-ce3f-4ed8-a8a6-00000000001f
2017-08-08 14:54:47,106 p=31837 u=root |   31848 1502204087.10650: WORKER PROCESS EXITING
2017-08-08 14:54:47,107 p=31837 u=root |   31837 1502204087.10729: marking switch1 as failed
2017-08-08 14:54:47,107 p=31837 u=root |   31837 1502204087.10762: marking host switch1 failed, current state: HOST STATE: block=2, task=1, rescue=0, always=0, run_state=ITERATING_TASKS, fail_state=FAILED_NONE, pending_setup=False, tasks child state? (None), rescue child state? (None), always child state? (None), did rescue? False, did start at task? False
2017-08-08 14:54:47,107 p=31837 u=root |   31837 1502204087.10781: ^ failed state is now: HOST STATE: block=2, task=1, rescue=0, always=0, run_state=ITERATING_COMPLETE, fail_state=FAILED_TASKS, pending_setup=False, tasks child state? (None), rescue child state? (None), always child state? (None), did rescue? False, did start at task? False
2017-08-08 14:54:47,108 p=31837 u=root |   31837 1502204087.10804: getting the next task for host switch1
2017-08-08 14:54:47,108 p=31837 u=root |   31837 1502204087.10822: host switch1 is done iterating, returning
2017-08-08 14:54:47,108 p=31837 u=root |  The full traceback is:
Traceback (most recent call last):
File "/opt/ansible/lib/ansible/executor/task_executor.py", line 125, in run
res = self._execute()
File "/opt/ansible/lib/ansible/executor/task_executor.py", line 526, in _execute
result = self._handler.run(task_vars=variables)
File "/opt/ansible/lib/ansible/plugins/action/ce.py", line 72, in run
socket_path = connection.run()
File "/opt/ansible/lib/ansible/plugins/connection/persistent.py", line 102, in run
out = p.stdout.readline()
ValueError: I/O operation on closed file

2017-08-08 14:54:47,108 p=31837 u=root |  fatal: [switch1]: FAILED! => {
"failed": true,
"msg": "Unexpected failure during module execution.",
"stdout": ""
}
2017-08-08 14:54:47,109 p=31837 u=root |   31837 1502204087.10901: no more pending results, returning what we have

# Fixed code
def run(self, tmp=None, task_vars=None):
    if self._play_context.connection != "local":
        return dict(
            failed=True,
            msg="invalid connection specified, expected connection=local, "
            "got %s" % self._play_context.connection,
        )

    provider = self.load_provider()
    transport = provider["transport"] or "cli"

    display.vvvv(
        "connection transport is %s" % transport, self._play_context.remote_addr
    )

    if transport == "cli":
        pc = copy.deepcopy(self._play_context)
        pc.connection = "network_cli"
        pc.network_os = "ce"
        pc.remote_addr = provider["host"] or self._play_context.remote_addr
        pc.port = int(provider["port"] or self._play_context.port or 22)
        pc.remote_user = provider["username"] or self._play_context.connection_user
        pc.password = provider["password"] or self._play_context.password
        pc.timeout = int(provider["timeout"] or C.PERSISTENT_COMMAND_TIMEOUT)
        self._task.args["provider"] = provider.update(
            host=pc.remote_addr,
            port=pc.port,
            username=pc.remote_user,
            password=pc.password,
        )
        display.vvv("using connection plugin %s" % pc.connection, pc.remote_addr)
        connection = self._shared_loader_obj.connection_loader.get(
            "persistent", pc, sys.stdin
        )

        socket_path = connection.run()
        display.vvvv("socket_path: %s" % socket_path, pc.remote_addr)
        if not socket_path:
            return {
                "failed": True,
                "msg": "unable to open shell. Please see: "
                + "https://docs.ansible.com/ansible/network_debug_troubleshooting.html#unable-to-open-shell",
            }

        # make sure we are in the right cli context which should be
        # enable mode and not config module
        rc, out, err = connection.exec_command("prompt()")
        while str(out).strip().endswith("]"):
            display.vvvv(
                "wrong context, sending exit to device", self._play_context.remote_addr
            )
            connection.exec_command("return")
            rc, out, err = connection.exec_command("prompt()")

        task_vars["ansible_socket"] = socket_path

    # make sure a transport value is set in args
    self._task.args["transport"] = transport
    self._task.args["provider"] = provider

    result = super(ActionModule, self).run(tmp, task_vars)
    return result