# Buggy code
def _do_handler_run(
    self, handler, handler_name, iterator, play_context, notified_hosts=None
):
    # FIXME: need to use iterator.get_failed_hosts() instead?
    # if not len(self.get_hosts_remaining(iterator._play)):
    #    self._tqm.send_callback('v2_playbook_on_no_hosts_remaining')
    #    result = False
    #    break
    self._tqm.send_callback("v2_playbook_on_handler_task_start", handler)

    if notified_hosts is None:
        notified_hosts = self._notified_handlers[handler_name]

    run_once = False
    try:
        action = action_loader.get(handler.action, class_only=True)
        if handler.run_once or getattr(action, "BYPASS_HOST_LOOP", False):
            run_once = True
    except KeyError:
        # we don't care here, because the action may simply not have a
        # corresponding action plugin
        pass

    host_results = []
    for host in notified_hosts:
        if not handler.has_triggered(host) and (
            host.name not in self._tqm._failed_hosts or play_context.force_handlers
        ):
            task_vars = self._variable_manager.get_vars(
                loader=self._loader, play=iterator._play, host=host, task=handler
            )
            self.add_tqm_variables(task_vars, play=iterator._play)
            self._queue_task(host, handler, task_vars, play_context)
            if run_once:
                break

    # collect the results from the handler run
    host_results = self._wait_on_pending_results(iterator)

    try:
        included_files = IncludedFile.process_include_results(
            host_results,
            self._tqm,
            iterator=iterator,
            loader=self._loader,
            variable_manager=self._variable_manager,
        )
    except AnsibleError as e:
        return False

    result = True
    if len(included_files) > 0:
        for included_file in included_files:
            try:
                new_blocks = self._load_included_file(
                    included_file, iterator=iterator, is_handler=True
                )
                # for every task in each block brought in by the include, add the list
                # of hosts which included the file to the notified_handlers dict
                for block in new_blocks:
                    iterator._play.handlers.append(block)
                    for task in block.block:
                        result = self._do_handler_run(
                            handler=task,
                            iterator=iterator,
                            play_context=play_context,
                            notified_hosts=included_file._hosts[:],
                        )
                        if not result:
                            break
            except AnsibleError as e:
                for host in included_file._hosts:
                    iterator.mark_host_failed(host)
                    self._tqm._failed_hosts[host.name] = True
                display.warning(str(e))
                continue

    # wipe the notification list
    self._notified_handlers[handler_name] = []
    display.debug("done running handlers, result is: %s" % result)
    return result


# Traceback (TypeError)
Unexpected Exception: _do_handler_run() takes at least 5 arguments (5 given)
the full traceback was:

Traceback (most recent call last):
File "/usr/bin/ansible-playbook", line 84, in <module>
sys.exit(cli.run())
File "/usr/lib/python2.7/site-packages/ansible/cli/playbook.py", line 149, in run
results = pbex.run()
File "/usr/lib/python2.7/site-packages/ansible/executor/playbook_executor.py", line 149, in run
result = self._tqm.run(play=play)
File "/usr/lib/python2.7/site-packages/ansible/executor/task_queue_manager.py", line 249, in run
play_return = strategy.run(iterator, play_context)
File "/usr/lib/python2.7/site-packages/ansible/plugins/strategy/linear.py", line 205, in run
self._execute_meta(task, play_context, iterator)
File "/usr/lib/python2.7/site-packages/ansible/plugins/strategy/__init__.py", line 641, in _execute_meta
self.run_handlers(iterator, play_context)
File "/usr/lib/python2.7/site-packages/ansible/plugins/strategy/__init__.py", line 528, in run_handlers
result = self._do_handler_run(handler, handler_name, iterator=iterator, play_context=play_context)
File "/usr/lib/python2.7/site-packages/ansible/plugins/strategy/__init__.py", line 592, in _do_handler_run
notified_hosts=included_file._hosts[:],
TypeError: _do_handler_run() takes at least 5 arguments (5 given)

# Fixed code
def _do_handler_run(
    self, handler, handler_name, iterator, play_context, notified_hosts=None
):
    # FIXME: need to use iterator.get_failed_hosts() instead?
    # if not len(self.get_hosts_remaining(iterator._play)):
    #    self._tqm.send_callback('v2_playbook_on_no_hosts_remaining')
    #    result = False
    #    break
    self._tqm.send_callback("v2_playbook_on_handler_task_start", handler)

    if notified_hosts is None:
        notified_hosts = self._notified_handlers[handler_name]

    run_once = False
    try:
        action = action_loader.get(handler.action, class_only=True)
        if handler.run_once or getattr(action, "BYPASS_HOST_LOOP", False):
            run_once = True
    except KeyError:
        # we don't care here, because the action may simply not have a
        # corresponding action plugin
        pass

    host_results = []
    for host in notified_hosts:
        if not handler.has_triggered(host) and (
            host.name not in self._tqm._failed_hosts or play_context.force_handlers
        ):
            task_vars = self._variable_manager.get_vars(
                loader=self._loader, play=iterator._play, host=host, task=handler
            )
            self.add_tqm_variables(task_vars, play=iterator._play)
            self._queue_task(host, handler, task_vars, play_context)
            if run_once:
                break

    # collect the results from the handler run
    host_results = self._wait_on_pending_results(iterator)

    try:
        included_files = IncludedFile.process_include_results(
            host_results,
            self._tqm,
            iterator=iterator,
            inventory=self._inventory,
            loader=self._loader,
            variable_manager=self._variable_manager,
        )
    except AnsibleError as e:
        return False

    result = True
    if len(included_files) > 0:
        for included_file in included_files:
            try:
                new_blocks = self._load_included_file(
                    included_file, iterator=iterator, is_handler=True
                )
                # for every task in each block brought in by the include, add the list
                # of hosts which included the file to the notified_handlers dict
                for block in new_blocks:
                    iterator._play.handlers.append(block)
                    for task in block.block:
                        result = self._do_handler_run(
                            handler=task,
                            handler_name=None,
                            iterator=iterator,
                            play_context=play_context,
                            notified_hosts=included_file._hosts[:],
                        )
                        if not result:
                            break
            except AnsibleError as e:
                for host in included_file._hosts:
                    iterator.mark_host_failed(host)
                    self._tqm._failed_hosts[host.name] = True
                display.warning(str(e))
                continue

    # wipe the notification list
    self._notified_handlers[handler_name] = []
    display.debug("done running handlers, result is: %s" % result)
    return result