Ansible: Custom facts - error loading facts as JSON or ini

As noted in the documentation, the file should be marked as executable if you want it to be executed, otherwise it is treated as a static file containing structured data. To test this you should be executing the file directly (/etc/ansible/facts.d/try.fact), not passing it to sh.

chmod +x /etc/ansible/facts.d/try.fact
/etc/ansible/facts.d/try.fact

Let's use a simple playbook

- hosts: localhost
  gather_facts: true
  tasks:
    - debug:
        var: ansible_local

Both, sh/bash and the python scripts

shell> cat /etc/ansible/facts.d/try-exe.fact
#!/bin/sh
printf '%s' '{"thing": "value"}'
shell> cat /etc/ansible/facts.d/try-exe.fact
#!/usr/bin/env python
import sys
print('{"thing": "value"}')
shell> /etc/ansible/facts.d/try-exe.fact
{"thing": "value"}

work as expected

TASK [debug] ******************************************************
ok: [localhost] => 
  ansible_local:
    try-exe:
      thing: value

Also, static files both JSON and INI work as expected

shell> cat /etc/ansible/facts.d/try-json.fact
{"thing": "value"}
shell> cat /etc/ansible/facts.d/try-ini.fact
[default]
thing=value

give

TASK [debug] *******************************************************
ok: [localhost] => 
  ansible_local:
    try-ini:
      default:
        thing: value
    try-json:
      thing: value