# Issue with selectattr

**URL:** <https://forum.ansible.com/t/issue-with-selectattr/38698>\
**Category:** Ansible Project\
**Created:** [February 23, 2024, 4:30pm UTC](https://forum.ansible.com/t/issue-with-selectattr/38698 "2024-02-23T16:30:47Z")\
**Posts on this page:** 14\
**Page:** 1

<div class="post-metadata">

**Author:** ![harry\_devine](https://sea1.discourse-cdn.com/ansible/user_avatar/forum.ansible.com/harry_devine/32/5293_2.png) [@harry\_devine](https://forum.ansible.com/u/harry_devine)\
**Post date:** [February 23, 2024, 4:30pm UTC](https://forum.ansible.com/t/issue-with-selectattr/38698/1 "2024-02-23T16:30:47Z")

</div>

I am trying to determine when user’s password’s are going to expire in the next 10 days. After I traverse my FreeIPA users and store those users into a variable, I try to set a fact like so:

- name: Find users who’s password will expire in the next 10 days  
set\_fact:  
pwd\_expire\_soon: “{{ user\_show.results | json\_query(‘[\*].json.result.result.{uid: uid[0], pwdchg: krblastpwdchange[0]. **datetime** }’) | selectattr(‘pwdchg’, ‘lessthan’, ‘expire\_date’) | list }}”

When I run my playbook, I get the following error:

fatal: [localhost]: FAILED! =\> {“msg”: “Unexpected templating type error occurred on ({{ user\_show.results | json\_query(‘[\*].json.result.result.{uid: uid[0], pwdchg: krblastpwdchange[0]. **datetime** }’) | selectattr(‘pwdchg’, ‘lessthan’, ‘expire\_date’) | list }}): ‘\<’ not supported between instances of ‘NoneType’ and ‘str’. ‘\<’ not supported between instances of ‘NoneType’ and ‘str’”}

I can’t seem to find what the issue is. I originally had ‘\<’ instead of ‘lessthan’ but got the same error. Any ideas?

Thanks,  
Harry

---

<div class="post-metadata">

**Author:** ![Walter\_Rowe](https://sea1.discourse-cdn.com/ansible/user_avatar/forum.ansible.com/walter_rowe/32/4506_2.png) [@Walter\_Rowe](https://forum.ansible.com/u/Walter_Rowe)\
**Post date:** [February 23, 2024, 4:52pm UTC](https://forum.ansible.com/t/issue-with-selectattr/38698/2 "2024-02-23T16:52:49Z")

</div>

pwd\_expire\_soon: “{{ user\_show.results | json\_query(‘[\*].json.result.result.{uid: uid[0], pwdchg: krblastpwdchange[0]. **datetime** }’) | selectattr(‘pwdchg’, ‘lessthan’, ‘expire\_date’) | list }}”

What are you expecting this red portion to do? I don’t think it is valid in json\_query.

Walter

---

<div class="post-metadata">

**Author:** ![harry\_devine](https://sea1.discourse-cdn.com/ansible/user_avatar/forum.ansible.com/harry_devine/32/5293_2.png) [@harry\_devine](https://forum.ansible.com/u/harry_devine)\
**Post date:** [February 23, 2024, 5:09pm UTC](https://forum.ansible.com/t/issue-with-selectattr/38698/3 "2024-02-23T17:09:41Z")

</div>

Just pull out those fields from the returned user information. I use that in 2 or 3 other playbooks so I know that it works.

Thanks,  
Harry

---

<div class="post-metadata">

**Author:** ![Walter\_Rowe](https://sea1.discourse-cdn.com/ansible/user_avatar/forum.ansible.com/walter_rowe/32/4506_2.png) [@Walter\_Rowe](https://forum.ansible.com/u/Walter_Rowe)\
**Post date:** [February 23, 2024, 5:12pm UTC](https://forum.ansible.com/t/issue-with-selectattr/38698/4 "2024-02-23T17:12:53Z")

</div>

{{ user\_show.results | json\_query(‘[\*].json.result.result.{uid: uid[0], pwdchg: krblastpwdchange[0]. **datetime** }’) }}

I would display this info in a debug to see what the resulting data stream looks like. Maybe the selectattr(‘pwdchg’) is in inaccurate reference to pwdchg?

Walter

---

<div class="post-metadata">

**Author:** ![harry\_devine](https://sea1.discourse-cdn.com/ansible/user_avatar/forum.ansible.com/harry_devine/32/5293_2.png) [@harry\_devine](https://forum.ansible.com/u/harry_devine)\
**Post date:** [February 23, 2024, 6:05pm UTC](https://forum.ansible.com/t/issue-with-selectattr/38698/5 "2024-02-23T18:05:34Z")

</div>

Looks OK to me:

TASK [Show user info] \*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*  
ok: [localhost] =\> {  
“msg”: [  
{  
“pwdchg”: “20210416141027Z”,  
“uid”: “user1”  
}  
]  
}

Thanks,  
Harry

---

<div class="post-metadata">

**Author:** ![utoddl](https://sea1.discourse-cdn.com/ansible/user_avatar/forum.ansible.com/utoddl/32/249_2.png) [@utoddl](https://forum.ansible.com/u/utoddl)\
**Post date:** [February 23, 2024, 6:57pm UTC](https://forum.ansible.com/t/issue-with-selectattr/38698/6 "2024-02-23T18:57:45Z")

</div>

Without showing us the expression you used in your debug’s “msg:”, this doesn’t tell us anything.

---

<div class="post-metadata">

**Author:** ![harry\_devine](https://sea1.discourse-cdn.com/ansible/user_avatar/forum.ansible.com/harry_devine/32/5293_2.png) [@harry\_devine](https://forum.ansible.com/u/harry_devine)\
**Post date:** [February 23, 2024, 7:09pm UTC](https://forum.ansible.com/t/issue-with-selectattr/38698/7 "2024-02-23T19:09:24Z")

</div>

I’m not including the entire playbook, but the URI module call where user\_show gets registered, then the debug statements:

- name: Run user\_show from IDM API using previously stored session cookie  
ansible.builtin.uri:  
url: “https://{{idmfqdn}}/ipa/session/json”  
method: POST  
headers:  
Cookie: “{{ login.set\_cookie }}”  
Referer: “https://{{idmfqdn}}/ipa”  
Content-Type: “application/json”  
Accept: “application/json”  
body\_format: json  
body: “{"method": "user\_show","params": [["{{ item }}"],{"all": true,"version": "{{ api\_vers }}"}]}”  
register: user\_show  
loop: “{{ uid | json\_query(‘[:10]’) }}”

- name: Set expire date  
ansible.builtin.set\_fact:  
expire\_date: ‘{{ lookup(’‘pipe’‘, ‘‘date -u --date=“today + 10 days” +%Y%m%d000000Z’’) }}’

- name: Show expire date  
ansible.builtin.debug:  
msg: “{{ expire\_date }}”

- name: Show user info  
debug:  
msg: “{{ user\_show.results | json\_query(‘[\*].json.result.result.{uid: uid[0], pwdchg: krblastpwdchange[0]. **datetime** }’) }}”

Thanks,  
Harry

---

<div class="post-metadata">

**Author:** ![utoddl](https://sea1.discourse-cdn.com/ansible/user_avatar/forum.ansible.com/utoddl/32/249_2.png) [@utoddl](https://forum.ansible.com/u/utoddl)\
**Post date:** [February 23, 2024, 7:45pm UTC](https://forum.ansible.com/t/issue-with-selectattr/38698/8 "2024-02-23T19:45:51Z")

</div>

The original problem is you’re comparing ‘NoneType’ and ‘str’. So, for at least one of your principals there’s no krblastpwdchange. You need to work on the subset of data relevant to the comparison.

---

<div class="post-metadata">

**Author:** ![harry\_devine](https://sea1.discourse-cdn.com/ansible/user_avatar/forum.ansible.com/harry_devine/32/5293_2.png) [@harry\_devine](https://forum.ansible.com/u/harry_devine)\
**Post date:** [February 23, 2024, 7:54pm UTC](https://forum.ansible.com/t/issue-with-selectattr/38698/9 "2024-02-23T19:54:06Z")

</div>

So it looks like the VERY 1st user in our system has never logged in, so the krblaspwdchange property has never gotten set. Is there a way to ignore when that field doesn’t exist or is null?

Thanks,  
Harry

---

<div class="post-metadata">

**Author:** ![harry\_devine](https://sea1.discourse-cdn.com/ansible/user_avatar/forum.ansible.com/harry_devine/32/5293_2.png) [@harry\_devine](https://forum.ansible.com/u/harry_devine)\
**Post date:** [February 26, 2024, 2:43pm UTC](https://forum.ansible.com/t/issue-with-selectattr/38698/10 "2024-02-26T14:43:31Z")

</div>

I’m including the playbook below. I’m still unable to find a way to ignore any user that does not have the krblastpwdchange property set. When I run the playbook, I still get the following error:

TASK [Find users who’s password will expire in the next 10 days] \*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*  
fatal: [localhost]: FAILED! =\> {“msg”: “Unexpected templating type error occurred on ({{ user\_show.results | json\_query(‘[\*].json.result.result.{uid: uid[0], pwdchg: krblastpwdchange[0]. **datetime** }’) | selectattr(‘pwdchg’, ‘defined’) | selectattr(‘pwdchg’, ‘\<’, expire\_date) | list }}): ‘\<’ not supported between instances of ‘NoneType’ and ‘AnsibleUnsafeText’. ‘\<’ not supported between instances of ‘NoneType’ and ‘AnsibleUnsafeText’”}

Playbook:

---

<div class="post-metadata">

**Author:** ![utoddl](https://sea1.discourse-cdn.com/ansible/user_avatar/forum.ansible.com/utoddl/32/249_2.png) [@utoddl](https://forum.ansible.com/u/utoddl)\
**Post date:** [February 26, 2024, 7:14pm UTC](https://forum.ansible.com/t/issue-with-selectattr/38698/11 "2024-02-26T19:14:01Z")

</div>

Normally I would change

```auto
krblastpwdchange[0]. __datetime__

```

to

```auto
krblastpwdchange[0]. __datetime__ | default('0')

```

but your expression is part of json\_query(). Perhaps there’s an equivalent of Jinja’s default() in json\_query(); I just don’t know.

Without standing up an IPA instance and experimenting, I don’t see a way to derive what your user\_show data looks like. (I did that a year or two ago to answer a similar question, but I’m a bit swamped at the moment.) Perhaps if you could give us the first couple of records from your registered user\_show data — the first one that’s throwing the error and another one or two that has what you expect, anonymized as appropriate of course — that would give us enough information about your data’s structure to suggest some expressions to try.

Including the playbook helps a whole lot; alas, without sample data or an IPA instance to play with it’s not sufficient to give you a definitive answer. Well, at least I can’t.

I know this sort of problem can be extremely frustrating, and you’ve been patient in asking. We really do want to help, honestly. But the IPA thing is one level of niche, and very few people are versed in json\_query() so that adds yet another level of niche. But if you can provide the sample data I mentioned before I think we can make some progress.

---

<div class="post-metadata">

**Author:** ![harry\_devine](https://sea1.discourse-cdn.com/ansible/user_avatar/forum.ansible.com/harry_devine/32/5293_2.png) [@harry\_devine](https://forum.ansible.com/u/harry_devine)\
**Post date:** [February 26, 2024, 7:27pm UTC](https://forum.ansible.com/t/issue-with-selectattr/38698/12 "2024-02-26T19:27:46Z")

</div>

I totally understand where you’re coming from. You guys have always been great and extremely helpful, and I appreciate that. I have adjusted the playbook to look at the first 5 users, and the anonymized output is below.

Thanks,  
Harry

TASK [Show user info] \*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*  
ok: [localhost] =\> {  
“msg”: [  
{  
“pwdchg”: null,  
“uid”: “user1”  
},  
{  
“pwdchg”: “20240124144409Z”,  
“uid”: “user2”  
},  
{  
“pwdchg”: “20231212115535Z”,  
“uid”: “user3”  
},  
{  
“pwdchg”: null,  
“uid”: “user4”  
},  
{  
“pwdchg”: “20240115133407Z”,  
“uid”: “user5”  
}  
]  
}

---

<div class="post-metadata">

**Author:** ![utoddl](https://sea1.discourse-cdn.com/ansible/user_avatar/forum.ansible.com/utoddl/32/249_2.png) [@utoddl](https://forum.ansible.com/u/utoddl)\
**Post date:** [February 26, 2024, 7:49pm UTC](https://forum.ansible.com/t/issue-with-selectattr/38698/13 "2024-02-26T19:49:22Z")

</div>

Assuming what you posted is the result of:

```auto
  - name: Show user info
      debug:
        msg: "{{ user_show.results | json_query('[*].json.result.result.{uid: uid[0], pwdchg: krblastpwdchange[0]. __datetime__ }') }}"

```

Then throw this onto the end:

```auto
  > selectattr("pwdchg", "!=", None)

```

You could put that new expression in a set\_fact for use later on.

---

<div class="post-metadata">

**Author:** ![harry\_devine](https://sea1.discourse-cdn.com/ansible/user_avatar/forum.ansible.com/harry_devine/32/5293_2.png) [@harry\_devine](https://forum.ansible.com/u/harry_devine)\
**Post date:** [February 26, 2024, 8:54pm UTC](https://forum.ansible.com/t/issue-with-selectattr/38698/14 "2024-02-26T20:54:44Z")

</div>

I think I got it. I set the fact like so:

- name: Find users who’s password will expire in the next {{ warning\_days }} days  
ansible.builtin.set\_fact:  
pwd\_expire\_soon: “{{ user\_show.results | json\_query(‘[\*].json.result.result.{uid: uid[0], pwdchg: krblastpwdchange[0]. **datetime** }’) | selectattr(‘pwdchg’, ‘!=’, None) | selectattr(‘pwdchg’, ‘\<’, expire\_date) | list }}”

And that returns those 3 that did not have null for krblastpwdchange. Now, those 3 had values that were within the last 30/60 days, but I think I may be looking at the wrong attribute at this point. But that’s something that I’ll work on next.

Thank you very much for your help and time! I always appreciate you guys!  
Harry
