Repository: ansible/ansible

Issue:
backtrace with simple task
Not sure how useful this will be, but this reliably backtraces for me with devel from today:

```

---
# tasks file for ntoggle.common
- name: Install base packages
  yum: pkg={{item}} state=present
  with_items: "{{base_packages}}"
  tags: packages
```

```
# roles/ntoggle.common/defaults/main.yml

---
# defaults file for ntoggle.common
base_packages:
 # For debugging
 - 'dstat'
 # Used for installing docker-py
 - 'python-pip'
 # Used by url within ansible for assertions.
 - 'python-httplib2'
 # For long-running processes when manually running load tests
 - 'screen'
 # So that we can reconnect once in a while.
 - 'mosh'
 # We need to be able to run netstat in datadog
 - 'net-tools'
```

```
TASK [../roles/ntoggle.common : ../roles/ntoggle.common : Install base packages]
An exception occurred during task execution. The full traceback is:
Traceback (most recent call last):
  File "/home/apenney/ansible/lib/ansible/executor/process/worker.py", line 118, in run
    executor_result = TaskExecutor(host, task, job_vars, new_connection_info, self._new_stdin, self._loader, shared_loader_obj).run()
  File "/home/apenney/ansible/lib/ansible/executor/task_executor.py", line 83, in run
    item_results = self._run_loop(items)
  File "/home/apenney/ansible/lib/ansible/executor/task_executor.py", line 151, in _run_loop
    items = self._squash_items(items, task_vars)
  File "/home/apenney/ansible/lib/ansible/executor/task_executor.py", line 189, in _squash_items
    if templar._contains_vars(self._task.args['name']):
KeyError: 'name'
```



Discussion:
Smaller playbook for reproduction:

```
---
- hosts: all
  gather_facts: false
  tasks:
    - yum: pkg="{{ item }}"
      with_items:
        - 'python'
```

Replacing `pkg` with `name` in the task resolves the issue.

I'll look into this a bit more, but the following seems to address the issue:

```
diff --git a/lib/ansible/executor/task_executor.py b/lib/ansible/executor/task_executor.py
index 8405389..1f46b0c 100644
--- a/lib/ansible/executor/task_executor.py
+++ b/lib/ansible/executor/task_executor.py
@@ -179,15 +179,15 @@ class TaskExecutor:
         Squash items down to a comma-separated list for certain modules which support it
         (typically package management modules).
         '''
         if len(items) > 0 and self._task.action in self.SQUASH_ACTIONS:
             final_items = []
             for item in items:
                 variables['item'] = item
                 templar = Templar(loader=self._loader, shared_loader_obj=self._shared_loader_obj, variables=variables)
                 if self._task.evaluate_conditional(templar, variables):
-                    if templar._contains_vars(self._task.args['name']):
-                        new_item = templar.template(self._task.args['name'])
+                    name = self._task.args.pop('name', None) or self._task.args.pop('pkg', None)
+                    if templar._contains_vars(name):
+                        new_item = templar.template(name)
                         final_items.append(new_item)
                     else:
                         final_items.append(item)
```


Resolving patch:
diff --git a/lib/ansible/executor/task_executor.py b/lib/ansible/executor/task_executor.py
--- a/lib/ansible/executor/task_executor.py
+++ b/lib/ansible/executor/task_executor.py
@@ -179,15 +179,15 @@ def _squash_items(self, items, variables):
         Squash items down to a comma-separated list for certain modules which support it
         (typically package management modules).
         '''
-
         if len(items) > 0 and self._task.action in self.SQUASH_ACTIONS:
             final_items = []
             for item in items:
                 variables['item'] = item
                 templar = Templar(loader=self._loader, shared_loader_obj=self._shared_loader_obj, variables=variables)
                 if self._task.evaluate_conditional(templar, variables):
-                    if templar._contains_vars(self._task.args['name']):
-                        new_item = templar.template(self._task.args['name'])
+                    name = self._task.args.pop('name', None) or self._task.args.pop('pkg', None)
+                    if templar._contains_vars(name):
+                        new_item = templar.template(name)
                         final_items.append(new_item)
                     else:
                         final_items.append(item)


Test patch: