Just to expand on Vladimir Botka's response, you really need to check to make sure your item is a list (or a dictionary) first! It's very easy to make a mistake around type checking, as this can be a very easy slip-up to make.
Just to prove this, here's a sample playbook:
---
- hosts: localhost
gather_facts: false
vars:
a_string: abcd1234
a_list: ['a', 'short', 'list']
a_dict: {'a': 'dictionary', 'with': 'values'}
tasks:
- debug:
msg: |
[
"a_string length: {{ a_string | length }}",
"a_list length: {{ a_list | length }}",
"a_dict length: {{ a_dict | length }}"
]
And the result:
PLAY [localhost] ******************************************************************************************************************************
TASK [debug] **********************************************************************************************************************************
ok: [localhost] => {
"msg": [
"a_string length: 8",
"a_list length: 3",
"a_dict length: 2"
]
}
PLAY RECAP ************************************************************************************************************************************
localhost : ok=1 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
So, how can we confirm that this is, in fact, a list before we want to check the number of elements?
Like this:
{% if my_value is string %}
1
{% elif my_value is iterable %}
{{ my_value | length }}
{% endif %}
We have to check if it's a string first as strings are also iterable, whereas dictionaries (mapping) and lists (sequences) are not strings. Integers and Floats don't have a "length" property, so perhaps you should check for that first too (using if my_value is number
)?