# Buggy code
def run(self):
    """
    Called when the process is started.  Pushes the result onto the
    results queue. We also remove the host from the blocked hosts list, to
    signify that they are ready for their next task.
    """

    # import cProfile, pstats, StringIO
    # pr = cProfile.Profile()
    # pr.enable()

    if HAS_ATFORK:
        atfork()

    try:
        # execute the task and build a TaskResult from the result
        display.debug("running TaskExecutor() for %s/%s" % (self._host, self._task))
        executor_result = TaskExecutor(
            self._host,
            self._task,
            self._task_vars,
            self._play_context,
            self._new_stdin,
            self._loader,
            self._shared_loader_obj,
            self._rslt_q,
        ).run()

        display.debug(
            "done running TaskExecutor() for %s/%s" % (self._host, self._task)
        )
        self._host.vars = dict()
        self._host.groups = []
        task_result = TaskResult(
            self._host.name,
            self._task._uuid,
            executor_result,
            task_fields=self._task.dump_attrs(),
        )

        # put the result on the result queue
        display.debug("sending task result")
        self._rslt_q.put(task_result)
        display.debug("done sending task result")

    except AnsibleConnectionFailure:
        self._host.vars = dict()
        self._host.groups = []
        task_result = TaskResult(
            self._host.name,
            self._task._uuid,
            dict(unreachable=True),
            task_fields=self._task.dump_attrs(),
        )
        self._rslt_q.put(task_result, block=False)

    except Exception as e:
        if not isinstance(
            e, (IOError, EOFError, KeyboardInterrupt, SystemExit)
        ) or isinstance(e, TemplateNotFound):
            try:
                self._host.vars = dict()
                self._host.groups = []
                task_result = TaskResult(
                    self._host.name,
                    self._task._uuid,
                    dict(
                        failed=True,
                        exception=to_text(traceback.format_exc()),
                        stdout="",
                    ),
                    task_fields=self._task.dump_attrs(),
                )
                self._rslt_q.put(task_result, block=False)
            except:
                display.debug("WORKER EXCEPTION: %s" % to_text(e))
                display.debug("WORKER TRACEBACK: %s" % to_text(traceback.format_exc()))

    display.debug("WORKER PROCESS EXITING")


# Traceback (KeyError)
ansible-playbook -vvvv playbook.yml
No config file found; using defaults
[WARNING]: Host file not found: /etc/ansible/hosts

[WARNING]: provided hosts list is empty, only localhost is available

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

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

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

TASK [include_role] ************************************************************
task path: /Users/xxx/workspace/xxx/playbook.yml:6

TASK [handlertest : command] ***************************************************
task path: /Users/xxx/workspace/xxx/roles/handlertest/tasks/main.yml:3
Using module file /usr/local/lib/python2.7/site-packages/ansible/modules/core/commands/command.py
<127.0.0.1> ESTABLISH LOCAL CONNECTION FOR USER: xxx
<127.0.0.1> EXEC /bin/sh -c '( umask 77 &amp;&amp; mkdir -p "` echo $HOME/.ansible/tmp/ansible-tmp-1478572148.78-187995060050975 `" &amp;&amp; echo ansible-tmp-1478572148.78-187995060050975="` echo $HOME/.ansible/tmp/ansible-tmp-1478572148.78-187995060050975 `" ) &amp;&amp; sleep 0'
<127.0.0.1> PUT /var/folders/62/pqgvprd11fb4k6shw2pdzkqm0000gq/T/tmpGA2Gau TO /Users/xxx/.ansible/tmp/ansible-tmp-1478572148.78-187995060050975/command.py
<127.0.0.1> EXEC /bin/sh -c 'chmod u+x /Users/xxx/.ansible/tmp/ansible-tmp-1478572148.78-187995060050975/ /Users/xxx/.ansible/tmp/ansible-tmp-1478572148.78-187995060050975/command.py &amp;&amp; sleep 0'
<127.0.0.1> EXEC /bin/sh -c '/usr/local/opt/python/bin/python2.7 /Users/xxx/.ansible/tmp/ansible-tmp-1478572148.78-187995060050975/command.py; rm -rf "/Users/xxx/.ansible/tmp/ansible-tmp-1478572148.78-187995060050975/" > /dev/null 2>&amp;1 &amp;&amp; sleep 0'
ERROR! Unexpected Exception: HANDLER: handlertest : Some handler
the full traceback was:

Traceback (most recent call last):
File "/usr/local/bin/ansible-playbook", line 103, in <module>
exit_code = cli.run()
File "/usr/local/lib/python2.7/site-packages/ansible/cli/playbook.py", line 159, in run
results = pbex.run()
File "/usr/local/lib/python2.7/site-packages/ansible/executor/playbook_executor.py", line 154, in run
result = self._tqm.run(play=play)
File "/usr/local/lib/python2.7/site-packages/ansible/executor/task_queue_manager.py", line 282, in run
play_return = strategy.run(iterator, play_context)
File "/usr/local/lib/python2.7/site-packages/ansible/plugins/strategy/linear.py", line 278, in run
results += self._wait_on_pending_results(iterator)
File "/usr/local/lib/python2.7/site-packages/ansible/plugins/strategy/__init__.py", line 534, in _wait_on_pending_results
results = self._process_pending_results(iterator)
File "/usr/local/lib/python2.7/site-packages/ansible/plugins/strategy/__init__.py", line 399, in _process_pending_results
if original_host not in self._notified_handlers[target_handler]:
KeyError: HANDLER: handlertest : Some handler

# Fixed code
def run(self):
    """
    Called when the process is started.  Pushes the result onto the
    results queue. We also remove the host from the blocked hosts list, to
    signify that they are ready for their next task.
    """

    # import cProfile, pstats, StringIO
    # pr = cProfile.Profile()
    # pr.enable()

    if HAS_ATFORK:
        atfork()

    try:
        # execute the task and build a TaskResult from the result
        display.debug("running TaskExecutor() for %s/%s" % (self._host, self._task))
        executor_result = TaskExecutor(
            self._host,
            self._task,
            self._task_vars,
            self._play_context,
            self._new_stdin,
            self._loader,
            self._shared_loader_obj,
            self._rslt_q,
        ).run()

        display.debug(
            "done running TaskExecutor() for %s/%s [%s]"
            % (self._host, self._task, self._task._uuid)
        )
        self._host.vars = dict()
        self._host.groups = []
        task_result = TaskResult(
            self._host.name,
            self._task._uuid,
            executor_result,
            task_fields=self._task.dump_attrs(),
        )

        # put the result on the result queue
        display.debug("sending task result for task %s" % self._task._uuid)
        self._rslt_q.put(task_result)
        display.debug("done sending task result for task %s" % self._task._uuid)

    except AnsibleConnectionFailure:
        self._host.vars = dict()
        self._host.groups = []
        task_result = TaskResult(
            self._host.name,
            self._task._uuid,
            dict(unreachable=True),
            task_fields=self._task.dump_attrs(),
        )
        self._rslt_q.put(task_result, block=False)

    except Exception as e:
        if not isinstance(
            e, (IOError, EOFError, KeyboardInterrupt, SystemExit)
        ) or isinstance(e, TemplateNotFound):
            try:
                self._host.vars = dict()
                self._host.groups = []
                task_result = TaskResult(
                    self._host.name,
                    self._task._uuid,
                    dict(
                        failed=True,
                        exception=to_text(traceback.format_exc()),
                        stdout="",
                    ),
                    task_fields=self._task.dump_attrs(),
                )
                self._rslt_q.put(task_result, block=False)
            except:
                display.debug("WORKER EXCEPTION: %s" % to_text(e))
                display.debug("WORKER TRACEBACK: %s" % to_text(traceback.format_exc()))

    display.debug("WORKER PROCESS EXITING")