When condition expecting string instead of bool

Playbook when condition seems to be expecting a string, where it should take a boolean

We’re updating our ansible playbooks from 2.10 to 2.19 (ansible 12.0.0).
I’ve handled issues brought up by ansible-lint (v25.9.2).
It looks like using lookup() against ansible.builtin.env is making the parser expect the value to be a string when I try to use it for a when condition.

Playbook below reproduces the issue:

---
- name: Main playbook to configure the network
  hosts: all
  gather_facts: false
  vars:
    IM_A_BOOL: "{{ lookup('ansible.builtin.env', 'ENV_IM_A_BOOL') | bool }}"
  pre_tasks:
    - name: Pre-task block
      when: IM_A_BOOL  # Task failed: Error rendering template: sequence item 0: expected str instance, bool found
      block:
        - name: debug statement
          debug:
            msg: "I should print"

Executing the ansible-playbook with this results in the following:

# debug statement *********************************************************************************************************
  * switch          - FAILED!!! ------------------------------------------------------
    Task failed: Error rendering template: sequence item 0: expected str instance, bool found
    (traceback unavailable)

If I change the variable definition to a literal IM_A_BOOL: True, the when condition works.

Is this expected?
If so, how should the playbook be updated?

Thank you

1 Like

What value(s) have you used for your ENV_IM_A_BOOL environment variable? I’ve tried several with an exact copy-n-paste of your playbook in a new venv with a fresh ansible 12.0.0 installed, and I’m not getting what you’re getting.

(venv-ansible-2.19) utoddl@tango:~/ansible$ ENV_IM_A_BOOL=False ansible-playbook test-bool.yml -i localhost, -vv
ansible-playbook [core 2.19.3]
  config file = /etc/ansible/ansible.cfg
  configured module search path = ['/home/utoddl/.ansible/plugins/modules', '/usr/share/ansible/plugins/modules']
  ansible python module location = /opt/venv-ansible-2.19/lib64/python3.13/site-packages/ansible
  ansible collection location = /home/utoddl/.ansible/collections:/usr/share/ansible/collections
  executable location = /opt/venv-ansible-2.19/bin/ansible-playbook
  python version = 3.13.7 (main, Aug 14 2025, 00:00:00) [GCC 15.2.1 20250808 (Red Hat 15.2.1-1)] (/opt/venv-ansible-2.19/bin/python3)
  jinja version = 3.1.6
  pyyaml version = 6.0.3 (with libyaml v0.2.5)
Using /etc/ansible/ansible.cfg as config file
Skipping callback 'minimal', as we already have a stdout callback.
Skipping callback 'oneline', as we already have a stdout callback.

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

PLAY [Main playbook to configure the network] **********************************************************************

TASK [debug statement] *********************************************************************************************
task path: /home/utoddl/ansible/test-bool.yml:11
skipping: [localhost] => {"false_condition": "IM_A_BOOL"}

PLAY RECAP *********************************************************************************************************
localhost                  : ok=0    changed=0    unreachable=0    failed=0    skipped=1    rescued=0    ignored=0 

With ENV_IM_A_BOOL=False, I get the above output.

With ENV_IM_A_BOOL=Falser, I get

TASK [debug statement] *********************************************************************************************
task path: /home/utoddl/ansible/test-bool.yml:11
[WARNING]: Deprecation warnings can be disabled by setting `deprecation_warnings=False` in ansible.cfg.
[DEPRECATION WARNING]: The `bool` filter coerced invalid value 'Falser' (str) to False. This feature will be removed from ansible-core version 2.23.
skipping: [localhost] => {"false_condition": "IM_A_BOOL"}

With ENV_IM_A_BOOL=True, I get

TASK [debug statement] **************************
task path: /home/utoddl/ansible/test-bool.yml:11
ok: [localhost] => {
    "msg": "I should print"
}

And without an ENV_IM_A_BOOL environment variable I get

TASK [debug statement] *********************************************************************************************
task path: /home/utoddl/ansible/test-bool.yml:11
[WARNING]: Deprecation warnings can be disabled by setting `deprecation_warnings=False` in ansible.cfg.
[DEPRECATION WARNING]: The `bool` filter coerced invalid value '' (str) to False. This feature will be removed from ansible-core version 2.23.
skipping: [localhost] => {"false_condition": "IM_A_BOOL"}

Hope this helps.

1 Like

normally i recommend to ‘cast’ at consumption, not on definition, though after 2.19 this is less of an issue, still it creates more compatible plays:

when: IM_A_BOOL | bool

but to debug further i would show:

- debug: msg={{ lookup('env', 'ENV_IM_A_BOOL') }}

- debug: msg={{ lookup('env', 'ENV_IM_A_BOOL') | debug_type }}
1 Like