# The non-existence of local facts means Ansible cannot check the existence of a local fact

**URL:** <https://forum.ansible.com/t/the-non-existence-of-local-facts-means-ansible-cannot-check-the-existence-of-a-local-fact/30078>\
**Category:** Ansible Project\
**Created:** [April 8, 2019, 7:40pm UTC](https://forum.ansible.com/t/the-non-existence-of-local-facts-means-ansible-cannot-check-the-existence-of-a-local-fact/30078 "2019-04-08T19:40:05Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![Andy\_Wang](https://avatars.discourse-cdn.com/v4/letter/a/aca169/32.png) [@Andy\_Wang](https://forum.ansible.com/u/Andy_Wang)\
**Post date:** [April 8, 2019, 7:40pm UTC](https://forum.ansible.com/t/the-non-existence-of-local-facts-means-ansible-cannot-check-the-existence-of-a-local-fact/30078/1 "2019-04-08T19:40:05Z")

</div>

I have a playbook that checks the existence of a local fact, but not every hosts have this local fact.

On servers where it does not exist my playbook fails with:

“msg”: "The conditional check ‘ansible\_local[‘my\_fact’][‘default’][‘name’] is defined’ failed. The error was: error while evaluating conditional (ansible\_local[‘my\_fact’][‘default’][‘name’] is defined): ‘dict object’ has no attribute ‘my\_fact’

This is quite annoying. I think I can work around it by checking the existence of the local fact file, but it feels like I’m missing something obvious.

---

<div class="post-metadata">

**Author:** ![Kai\_Stian\_Olstad](https://avatars.discourse-cdn.com/v4/letter/k/e19adc/32.png) [@Kai\_Stian\_Olstad](https://forum.ansible.com/u/Kai_Stian_Olstad)\
**Post date:** [April 9, 2019, 5:43am UTC](https://forum.ansible.com/t/the-non-existence-of-local-facts-means-ansible-cannot-check-the-existence-of-a-local-fact/30078/2 "2019-04-09T05:43:50Z")

</div>

You need to use the default filter  
[https://docs.ansible.com/ansible/latest/user\_guide/playbooks\_filters.html#defaulting-undefined-variables](https://docs.ansible.com/ansible/latest/user_guide/playbooks_filters.html#defaulting-undefined-variables)

And you need to use the filter on every sub attribute.  
So something like this should work

((ansible\_local['my\_fact'] | default({}))['default'] | default({}))['name'] | default({})

---

<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:** [April 9, 2019, 1:30pm UTC](https://forum.ansible.com/t/the-non-existence-of-local-facts-means-ansible-cannot-check-the-existence-of-a-local-fact/30078/3 "2019-04-09T13:30:21Z")

</div>

or a more flexible conditional:

when: "'my\_fact' in ansible\_local and  
ansible\_local['my\_fact']['default']['name'] is defined"

FYI, in newer version of Ansilbe, `ansible_local` is always defined,  
even if empty, so no need to use default on it

---

<div class="post-metadata">

**Author:** ![Andy\_Wang](https://avatars.discourse-cdn.com/v4/letter/a/aca169/32.png) [@Andy\_Wang](https://forum.ansible.com/u/Andy_Wang)\
**Post date:** [April 10, 2019, 2:32pm UTC](https://forum.ansible.com/t/the-non-existence-of-local-facts-means-ansible-cannot-check-the-existence-of-a-local-fact/30078/4 "2019-04-10T14:32:00Z")

</div>

Sadly, neither the suggested solutions worked. I’m using Ansible 2.5.2 BTW.

---

<div class="post-metadata">

**Author:** ![Andy\_Wang](https://avatars.discourse-cdn.com/v4/letter/a/aca169/32.png) [@Andy\_Wang](https://forum.ansible.com/u/Andy_Wang)\
**Post date:** [April 10, 2019, 7:36pm UTC](https://forum.ansible.com/t/the-non-existence-of-local-facts-means-ansible-cannot-check-the-existence-of-a-local-fact/30078/5 "2019-04-10T19:36:05Z")

</div>

The workaround I came up with was:

- name: Check if local fact exists  
stat:  
path: /etc/ansible/facts.d/my\_fact.fact  
register: local\_fact

- name: Create empty local fact  
ini\_file:  
path: /etc/ansible/facts.d/my\_fact.fact  
section: “default”  
option: “{{ item.option }}”  
value: “{{ item.value }}”  
with\_items:

- { option: “name”, value: “” }

- { option: “key”, value: “” }  
when: local\_fact.stat.exists == False

- name: read local facts  
setup:  
filter=ansible\_local

---

<div class="post-metadata">

**Author:** ![Kai\_Stian\_Olstad](https://avatars.discourse-cdn.com/v4/letter/k/e19adc/32.png) [@Kai\_Stian\_Olstad](https://forum.ansible.com/u/Kai_Stian_Olstad)\
**Post date:** [April 13, 2019, 1:38pm UTC](https://forum.ansible.com/t/the-non-existence-of-local-facts-means-ansible-cannot-check-the-existence-of-a-local-fact/30078/6 "2019-04-13T13:38:23Z")

</div>

> or a more flexible conditional:
> 
> when: "'my\_fact' in ansible\_local and  
> ansible\_local['my\_fact']['default']['name'] is defined"

To OP you might need to add is defined on ansible\_local['my\_fact']['default'] too, depending on you variables.

> FYI, in newer version of Ansilbe, `ansible_local` is always defined,  
> even if empty, so no need to use default on it

FYI, I did not use default on ansible\_local, only my\_fact, default and name.
