ansible-collections / ansible-collections/cloud.common

`turbo_fail` crashes with `TypeError` when `params` includes `msg`

Open
#192 0 comments 0 reactions 0 assignees View on GitHub
needs_verified
Dominant language
Python
Stars
19
Forks
28
PR merge metrics
No merged PRs in 30d

Description

##### SUMMARY

The `cloud.common.turbo_fail` module raises a Python `TypeError` instead of failing gracefully when the `params` dictionary contains a `msg` key. This happens because the module passes `msg` twice to `fail_json`.

##### ISSUE TYPE
- Bug Report

##### COMPONENT NAME

turbo_fail
##### ANSIBLE VERSION

```paste below
ansible [core 2.18.8]
config file = None
configured module search path = ['/root/.ansible/plugins/modules', '/usr/share/ansible/plugins/modules']
ansible python module location = /usr/local/lib/python3.12/site-packages/ansible
ansible collection location = /root/.ansible/collections:/usr/share/ansible/collections
executable location = /usr/local/bin/ansible
python version = 3.12.10 (main, Apr 22 2025, 00:00:00) [GCC 14.2.1 20240912 (Red Hat 14.2.1-3)] (/usr/bin/python3.12)
jinja version = 3.1.6
libyaml = True
```

##### COLLECTION VERSION

```paste below
Collection Version
------------ -------
cloud.common 4.2.0
```

##### CONFIGURATION

```paste below

```

##### OS / ENVIRONMENT

##### STEPS TO REPRODUCE

```yaml
- hosts: localhost
gather_facts: false
tasks:
- name: Run turbo_fail with conflicting msg
cloud.common.turbo_fail:
params:
msg: "user-defined message"
extra: "value"
```

##### EXPECTED RESULTS

We would expect the task to fails gracefully with a clean error message.

##### ACTUAL RESULTS

```paste below

PLAY [localhost] **********************************************************************************************************************************************************************

TASK [Run turbo_fail with conflicting msg] ********************************************************************************************************************************************
task path: /y.yml:4
<127.0.0.1> ESTABLISH LOCAL CONNECTION FOR USER: root
<127.0.0.1> EXEC /bin/sh -c 'echo ~root && sleep 0'
<127.0.0.1> EXEC /bin/sh -c '( umask 77 && mkdir -p "` echo /root/.ansible/tmp `"&& mkdir "` echo /root/.ansible/tmp/ansible-tmp-1755431279.178766-247-203242999900107 `" && echo ansible-tmp-1755431279.178766-247-203242999900107="` echo /root/.ansible/tmp/ansible-tmp-1755431279.178766-247-203242999900107 `" ) && sleep 0'
Using module file /usr/local/lib/python3.12/site-packages/ansible_collections/cloud/common/plugins/modules/turbo_fail.py
<127.0.0.1> PUT /root/.ansible/tmp/ansible-local-244lpv_mr58/tmpxmesz_qt TO /root/.ansible/tmp/ansible-tmp-1755431279.178766-247-203242999900107/AnsiballZ_turbo_fail.py
<127.0.0.1> EXEC /bin/sh -c 'chmod u+rwx /root/.ansible/tmp/ansible-tmp-1755431279.178766-247-203242999900107/ /root/.ansible/tmp/ansible-tmp-1755431279.178766-247-203242999900107/AnsiballZ_turbo_fail.py && sleep 0'
<127.0.0.1> EXEC /bin/sh -c '/usr/bin/python3.12 /root/.ansible/tmp/ansible-tmp-1755431279.178766-247-203242999900107/AnsiballZ_turbo_fail.py && sleep 0'
<127.0.0.1> EXEC /bin/sh -c 'rm -f -r /root/.ansible/tmp/ansible-tmp-1755431279.178766-247-203242999900107/ > /dev/null 2>&1 && sleep 0'
fatal: [localhost]: FAILED! => {
"changed": false,
"invocation": {
"module_args": {
"params": {
"extra": "value",
"msg": "user-defined message"
}
}
},
"msg": [
" File \"\", line 198, in _run_module_as_main\n",
" File \"\", line 88, in _run_code\n",
" File \"/tmp/ansible_cloud.common.turbo_fail_payload_788tn_y6/ansible_cloud.common.turbo_fail_payload.zip/ansible_collections/cloud/common/plugins/module_utils/turbo/server.py\", line 420, in \n server.start()\n",
" File \"/tmp/ansible_cloud.common.turbo_fail_payload_788tn_y6/ansible_cloud.common.turbo_fail_payload.zip/ansible_collections/cloud/common/plugins/module_utils/turbo/server.py\", line 395, in start\n self.loop.run_forever()\n",
" File \"/usr/lib64/python3.12/asyncio/base_events.py\", line 645, in run_forever\n self._run_once()\n",
" File \"/usr/lib64/python3.12/asyncio/base_events.py\", line 1999, in _run_once\n handle._run()\n",
" File \"/usr/lib64/python3.12/asyncio/events.py\", line 88, in _run\n self._context.run(self._callback, *self._args)\n",
" File \"/tmp/ansible_cloud.common.turbo_fail_payload_788tn_y6/ansible_cloud.common.turbo_fail_payload.zip/ansible_collections/cloud/common/plugins/module_utils/turbo/server.py\", line 355, in handle\n result = await run_as_module(content, debug_mode=self.debug_mode)\n",
" File \"/tmp/ansible_cloud.common.turbo_fail_payload_788tn_y6/ansible_cloud.common.turbo_fail_payload.zip/ansible_collections/cloud/common/plugins/module_utils/turbo/server.py\", line 308, in run_as_module\n \"msg\": traceback.format_stack() + [str(e)],\n",
"Traceback (most recent call last):\n File \"/tmp/ansible_cloud.common.turbo_fail_payload_788tn_y6/ansible_cloud.common.turbo_fail_payload.zip/ansible_collections/cloud/common/plugins/module_utils/turbo/server.py\", line 208, in run\n self.module_class.main()\n File \"/tmp/ansible_cloud.common.turbo_fail_payload_788tn_y6/ansible_cloud.common.turbo_fail_payload.zip/ansible_collections/cloud/common/plugins/modules/turbo_fail.py\", line 54, in main\n run_module()\n File \"/tmp/ansible_cloud.common.turbo_fail_payload_788tn_y6/ansible_cloud.common.turbo_fail_payload.zip/ansible_collections/cloud/common/plugins/modules/turbo_fail.py\", line 49, in run_module\n module.fail_json(msg=msg, **module.params.get(\"params\"))\nTypeError: ansible_collections.cloud.common.plugins.module_utils.turbo.module.AnsibleTurboModule.fail_json() got multiple values for keyword argument 'msg'\n"
]
}

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

## Root Cause
In `run_module` the call:
```python
module.fail_json(msg=msg, **module.params.get("params"))
```
leads to duplicate keyword arguments if `params` contains a `msg` key.

Contributor guide

Open the contributing guide

Research direction

Start in plugins/modules/turbo_fail.py at run_module, where module.fail_json is called with msg and the expanded params dictionary. Reproduce the issue with the provided playbook and confirm completion when a params.msg value no longer causes a TypeError and the task fails with a clean error message.

Written by the indexing model from the issue text.

Assessment

Tech stack
python
Domain
devops
Issue type
Bug
Difficulty
2/5
Estimated time
1-3 hours
Activity status
Stale
Clarity
Clearly specified
Newbie friendliness
48/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.