# Unexpected behavior change in loop over debug task in 2.14.2 -\> 2.16 upgrade

**URL:** <https://forum.ansible.com/t/unexpected-behavior-change-in-loop-over-debug-task-in-2-14-2-2-16-upgrade/6833>\
**Category:** Get Help\
**Tags:** upgrade, loop\
**Created:** [June 28, 2024, 1:53pm UTC](https://forum.ansible.com/t/unexpected-behavior-change-in-loop-over-debug-task-in-2-14-2-2-16-upgrade/6833 "2024-06-28T13:53:39Z")\
**Posts on this page:** 4\
**Page:** 1

<div class="post-metadata">

**Author:** ![john.elion](https://avatars.discourse-cdn.com/v4/letter/j/e5b9ba/32.png) [@john.elion](https://forum.ansible.com/u/john.elion)\
**Post date:** [June 28, 2024, 1:53pm UTC](https://forum.ansible.com/t/unexpected-behavior-change-in-loop-over-debug-task-in-2-14-2-2-16-upgrade/6833/1 "2024-06-28T13:53:40Z")

</div>

My development team has used “complex variables” (i.e., references to specific dictionary fields) in loops over the debug task for a long time. Example:

```auto
- debug:
     var: "{{ item }}"
  with_items:
  - result.rc
  - result.stdout
  - result.stderr

```

We have done this in order to avoid dumping the whole dictionary, which can be much longer. Recently, we were unexpectedly upgraded from Ansible 2.14.2 to Ansible 2.16. We find that this behavior no longer works. Instead of printing the values for each field in the list, it now prints something that looks like a recursive reference error (i.e., “dict.field” is displayed as “{{ dict.field }}”).

A simple playbook (shown below, with output from both versions) demonstrates the change in behavior. (While trying to find a workaround, we have found that replacing “with\_items” with “loop” gives us a workaround in both versions, but we’re not sure why.)

This happens even if we just put the dictionary variable as a single entry in the loop.

Is the use of a dictionary field (instead of just a plain, undecorated variable name) allowed in the debug task? Can loops be applied to the debug task? Is the change in behavior expected?

# Thank you.

Playbook:

```auto
- hosts: installer
  gather_facts: false
  vars:
    result:
      rc: 0
      stdout: 'TASK OUTPUT'
      stderr: 'ERROR OUTPUT'
  tasks:
  - debug:
      var: "{{ item }}"
    with_items:
    - result.rc
    - result.stdout
    - result.stderr

  - debug:
      var: "{{ item }}"
    loop:
    - result.rc
    - result.stdout
    - result.stderr

```

Results on 2.14.2 (got what I expected)

```auto
PLAY [installer] ***************************************************************

TASK [debug] *******************************************************************
ok: [paas-installer] => (item=result.rc) => {
    "ansible_loop_var": "item",
    "item": "result.rc",
    "result.rc": "0"
}
ok: [paas-installer] => (item=result.stdout) => {
    "ansible_loop_var": "item",
    "item": "result.stdout",
    "result.stdout": "TASK OUTPUT"
}
ok: [paas-installer] => (item=result.stderr) => {
    "ansible_loop_var": "item",
    "item": "result.stderr",
    "result.stderr": "ERROR OUTPUT"
}

TASK [debug] *******************************************************************
ok: [paas-installer] => (item=result.rc) => {
    "ansible_loop_var": "item",
    "item": "result.rc",
    "result.rc": "0"
}
ok: [paas-installer] => (item=result.stdout) => {
    "ansible_loop_var": "item",
    "item": "result.stdout",
    "result.stdout": "TASK OUTPUT"
}
ok: [paas-installer] => (item=result.stderr) => {
    "ansible_loop_var": "item",
    "item": "result.stderr",
    "result.stderr": "ERROR OUTPUT"
}

PLAY RECAP *********************************************************************
paas-installer : ok=2 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0

```

Results on 2.16 (first debug task has unexpected results):

```auto
PLAY [installer] ***************************************************************

TASK [debug] *******************************************************************
ok: [paas-installer] => (item=result.rc) => {
    "ansible_loop_var": "item",
    "item": "result.rc",
    "result.rc": "{{result.rc}}"
}
ok: [paas-installer] => (item=result.stdout) => {
    "ansible_loop_var": "item",
    "item": "result.stdout",
    "result.stdout": "{{result.stdout}}"
}
ok: [paas-installer] => (item=result.stderr) => {
    "ansible_loop_var": "item",
    "item": "result.stderr",
    "result.stderr": "{{result.stderr}}"
}

TASK [debug] *******************************************************************
ok: [paas-installer] => (item=result.rc) => {
    "ansible_loop_var": "item",
    "item": "result.rc",
    "result.rc": "0"
}
ok: [paas-installer] => (item=result.stdout) => {
    "ansible_loop_var": "item",
    "item": "result.stdout",
    "result.stdout": "TASK OUTPUT"
}
ok: [paas-installer] => (item=result.stderr) => {
    "ansible_loop_var": "item",
    "item": "result.stderr",
    "result.stderr": "ERROR OUTPUT"
}

PLAY RECAP *********************************************************************
paas-installer : ok=2 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0

```

Version details:  
2.14.2 installation

```auto
ansible [core 2.14.2]
  config file = /etc/ansible/ansible.cfg
  configured module search path = ['/var/paas/tmp/plugins/modules', '/usr/share/ansible/plugins/modules']
  ansible python module location = /usr/lib/python3.11/site-packages/ansible
  ansible collection location = /var/paas/tmp/collections:/usr/share/ansible/collections
  executable location = /usr/bin/ansible
  python version = 3.11.5 (main, Sep 22 2023, 15:34:29) [GCC 8.5.0 20210514 (Red Hat 8.5.0-20)] (/usr/bin/python3.11)
  jinja version = 3.1.2
  libyaml = True

```

Upgraded 2.16 installation

```auto
ansible [core 2.16.3]
  config file = /etc/ansible/ansible.cfg
  configured module search path = ['/var/paas/tmp/plugins/modules', '/usr/share/ansible/plugins/modules']
  ansible python module location = /usr/lib/python3.12/site-packages/ansible
  ansible collection location = /var/paas/tmp/collections:/usr/share/ansible/collections
  executable location = /usr/bin/ansible
  python version = 3.12.1 (main, Feb 21 2024, 10:25:11) [GCC 8.5.0 20210514 (Red Hat 8.5.0-21)] (/usr/bin/python3.12)
  jinja version = 3.1.2
  libyaml = True

```

---

<div class="post-metadata">

**Author:** ![flowerysong](https://sea1.discourse-cdn.com/ansible/user_avatar/forum.ansible.com/flowerysong/32/2305_2.png) [@flowerysong](https://forum.ansible.com/u/flowerysong)\
**Post date:** [June 28, 2024, 3:43pm UTC](https://forum.ansible.com/t/unexpected-behavior-change-in-loop-over-debug-task-in-2-14-2-2-16-upgrade/6833/2 "2024-06-28T15:43:01Z")

</div>

It’s best to use `loop` instead of `with_items` for looping over a list, because it involves less magic. `with_items: ['foo']` is the equivalent of `loop: "{{ query('items', ['foo']) }}"`, which is itself surprising to most people and can have surprising behaviour. The change in behaviour is due to [the security fix that made it harder for data marked as unsafe to be evaluated](https://docs.ansible.com/ansible-core/2.17/porting_guides/porting_guide_core_2.17.html#playbook). The result of lookups (like `items`) is marked as unsafe [by default](https://docs.ansible.com/ansible/latest/reference_appendices/config.html#default-allow-unsafe-lookups), so `with_items` transforms your list into a list of unsafe strings.

It’s also best to avoid embedded templates entirely, and more efficient to use a non-loop construct here.

```yaml
  - debug:
      msg:
        rc: "{{ result.rc }}"
        stdout: "{{ result.stdout }}"
        stderr: "{{ result.stderr }}"

```

```plaintext
TASK [debug] *******************************************************************
ok: [localhost] =>
    msg:
        rc: 0
        stderr: ERROR OUTPUT
        stdout: TASK OUTPUT

```

---

<div class="post-metadata">

**Author:** ![john.elion](https://avatars.discourse-cdn.com/v4/letter/j/e5b9ba/32.png) [@john.elion](https://forum.ansible.com/u/john.elion)\
**Post date:** [June 28, 2024, 4:30pm UTC](https://forum.ansible.com/t/unexpected-behavior-change-in-loop-over-debug-task-in-2-14-2-2-16-upgrade/6833/3 "2024-06-28T16:30:43Z")

</div>

Wow. I had seen that information, but didn’t understand how it applied to my situation. I appreciate the detail here, including the backward compatibility and security detail link. I couldn’t have asked for a better reply. Thank you.

---

<div class="post-metadata">

**Author:** ![system](https://us1.discourse-cdn.com/ansible/original/1X/1882d9a01da5d8996a862359b0913cc568a39b84.svg) [@system](https://forum.ansible.com/u/system)\
**Post date:** [July 28, 2024, 4:31pm UTC](https://forum.ansible.com/t/unexpected-behavior-change-in-loop-over-debug-task-in-2-14-2-2-16-upgrade/6833/4 "2024-07-28T16:31:41Z")

</div>

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.
