# Buggy code
def _execute_meta(self, task, play_context, iterator, target_host):
    # meta tasks store their args in the _raw_params field of args,
    # since they do not use k=v pairs, so get that
    meta_action = task.args.get("_raw_params")

    # FIXME(s):
    # * raise an error or show a warning when a conditional is used
    #   on a meta task that doesn't support them

    def _evaluate_conditional(h):
        all_vars = self._variable_manager.get_vars(
            loader=self._loader, play=iterator._play, host=h, task=task
        )
        templar = Templar(loader=self._loader, variables=all_vars)
        return task.evaluate_conditional(templar, all_vars)

    skipped = False
    msg = ""
    if meta_action == "noop":
        # FIXME: issue a callback for the noop here?
        msg = "noop"
    elif meta_action == "flush_handlers":
        self.run_handlers(iterator, play_context)
        msg = "ran handlers"
    elif meta_action == "refresh_inventory":
        self._inventory.refresh_inventory()
        msg = "inventory successfully refreshed"
    elif meta_action == "clear_facts":
        if _evaluate_conditional(target_host):
            for host in self._inventory.get_hosts(iterator._play.hosts):
                self._variable_manager.clear_facts(host)
            msg = "facts cleared"
        else:
            skipped = True
    elif meta_action == "clear_host_errors":
        if _evaluate_conditional(target_host):
            for host in self._inventory.get_hosts(iterator._play.hosts):
                self._tqm._failed_hosts.pop(host.name, False)
                self._tqm._unreachable_hosts.pop(host.name, False)
                iterator._host_states[host.name].fail_state = iterator.FAILED_NONE
            msg = "cleared host errors"
        else:
            skipped = True
    elif meta_action == "end_play":
        if _evaluate_conditional(target_host):
            for host in self._inventory.get_hosts(iterator._play.hosts):
                if not host.name in self._tqm._unreachable_hosts:
                    iterator._host_states[
                        host.name
                    ].run_state = iterator.ITERATING_COMPLETE
            msg = "ending play"
    elif meta_action == "reset_connection":
        connection = connection_loader.get(
            play_context.connection, play_context, "/dev/null"
        )
        connection.reset()
        msg = "reset connection"
    else:
        raise AnsibleError(
            "invalid meta action requested: %s" % meta_action, obj=task._ds
        )

    result = {"msg": msg}
    if skipped:
        result["skipped"] = True
    else:
        result["changed"] = False

    display.vv("META: %s" % msg)

    return [TaskResult(target_host, task, result)]


# Traceback (AttributeError)
[vagrant@localhost infra-bootstrap]$ ansible-playbook --limit=core --inventory-file=/tmp/vagrant-ansible/inventory -vvv test.yml
Using /etc/ansible/ansible.cfg as config file
[WARNING]: Found both group and host with same name: core


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

PLAY [all] ***********************************************************************************************************************************************************

TASK [Gathering Facts] ***********************************************************************************************************************************************
Using module file /usr/lib/python2.7/site-packages/ansible/modules/system/setup.py
<core> ESTABLISH LOCAL CONNECTION FOR USER: vagrant
<core> EXEC /bin/sh -c 'echo ~ &amp;&amp; sleep 0'
<core> EXEC /bin/sh -c '( umask 77 &amp;&amp; mkdir -p "` echo /home/vagrant/.ansible/tmp/ansible-tmp-1492207079.55-247174731112807 `" &amp;&amp; echo ansible-tmp-1492207079.55-247174731112807="` echo /home/vagrant/.ansible/tmp/ansible-tmp-1492207079.55-247174731112807 `" ) &amp;&amp; sleep 0'
<core> PUT /tmp/tmpbuhXwS TO /home/vagrant/.ansible/tmp/ansible-tmp-1492207079.55-247174731112807/setup.py
<core> EXEC /bin/sh -c 'chmod u+x /home/vagrant/.ansible/tmp/ansible-tmp-1492207079.55-247174731112807/ /home/vagrant/.ansible/tmp/ansible-tmp-1492207079.55-247174731112807/setup.py &amp;&amp; sleep 0'
<core> EXEC /bin/sh -c '/usr/bin/python /home/vagrant/.ansible/tmp/ansible-tmp-1492207079.55-247174731112807/setup.py; rm -rf "/home/vagrant/.ansible/tmp/ansible-tmp-1492207079.55-247174731112807/" > /dev/null 2>&amp;1 &amp;&amp; sleep 0'
ok: [core]
META: ran handlers
ERROR! Unexpected Exception: 'NoneType' object has no attribute 'reset'
the full traceback was:

Traceback (most recent call last):
File "/usr/bin/ansible-playbook", line 109, in <module>
exit_code = cli.run()
File "/usr/lib/python2.7/site-packages/ansible/cli/playbook.py", line 154, in run
results = pbex.run()
File "/usr/lib/python2.7/site-packages/ansible/executor/playbook_executor.py", line 153, in run
result = self._tqm.run(play=play)
File "/usr/lib/python2.7/site-packages/ansible/executor/task_queue_manager.py", line 284, in run
play_return = strategy.run(iterator, play_context)
File "/usr/lib/python2.7/site-packages/ansible/plugins/strategy/linear.py", line 221, in run
results.extend(self._execute_meta(task, play_context, iterator, host))
File "/usr/lib/python2.7/site-packages/ansible/plugins/strategy/__init__.py", line 908, in _execute_meta
connection.reset()
AttributeError: 'NoneType' object has no attribute 'reset'

# Fixed code
def _execute_meta(self, task, play_context, iterator, target_host):
    # meta tasks store their args in the _raw_params field of args,
    # since they do not use k=v pairs, so get that
    meta_action = task.args.get("_raw_params")

    # FIXME(s):
    # * raise an error or show a warning when a conditional is used
    #   on a meta task that doesn't support them

    def _evaluate_conditional(h):
        all_vars = self._variable_manager.get_vars(
            loader=self._loader, play=iterator._play, host=h, task=task
        )
        templar = Templar(loader=self._loader, variables=all_vars)
        return task.evaluate_conditional(templar, all_vars)

    skipped = False
    msg = ""
    if meta_action == "noop":
        # FIXME: issue a callback for the noop here?
        msg = "noop"
    elif meta_action == "flush_handlers":
        self.run_handlers(iterator, play_context)
        msg = "ran handlers"
    elif meta_action == "refresh_inventory":
        self._inventory.refresh_inventory()
        msg = "inventory successfully refreshed"
    elif meta_action == "clear_facts":
        if _evaluate_conditional(target_host):
            for host in self._inventory.get_hosts(iterator._play.hosts):
                self._variable_manager.clear_facts(host)
            msg = "facts cleared"
        else:
            skipped = True
    elif meta_action == "clear_host_errors":
        if _evaluate_conditional(target_host):
            for host in self._inventory.get_hosts(iterator._play.hosts):
                self._tqm._failed_hosts.pop(host.name, False)
                self._tqm._unreachable_hosts.pop(host.name, False)
                iterator._host_states[host.name].fail_state = iterator.FAILED_NONE
            msg = "cleared host errors"
        else:
            skipped = True
    elif meta_action == "end_play":
        if _evaluate_conditional(target_host):
            for host in self._inventory.get_hosts(iterator._play.hosts):
                if not host.name in self._tqm._unreachable_hosts:
                    iterator._host_states[
                        host.name
                    ].run_state = iterator.ITERATING_COMPLETE
            msg = "ending play"
    elif meta_action == "reset_connection":
        connection = connection_loader.get(
            play_context.connection, play_context, os.devnull
        )
        if connection:
            connection.reset()
            msg = "reset connection"
        else:
            msg = "no connection, nothing to reset"
    else:
        raise AnsibleError(
            "invalid meta action requested: %s" % meta_action, obj=task._ds
        )

    result = {"msg": msg}
    if skipped:
        result["skipped"] = True
    else:
        result["changed"] = False

    display.vv("META: %s" % msg)

    return [TaskResult(target_host, task, result)]