Skip to content

Fix module.run: positional arg for defaulted param raises 'multiple values' - #70083

Open
HarnageaGabriel wants to merge 1 commit into
saltstack:masterfrom
HarnageaGabriel:fix-module-run-positional-default-arg
Open

Fix module.run: positional arg for defaulted param raises 'multiple values'#70083
HarnageaGabriel wants to merge 1 commit into
saltstack:masterfrom
HarnageaGabriel:fix-module-run-positional-default-arg

Conversation

@HarnageaGabriel

Copy link
Copy Markdown

Summary

Fixes #69919.

module.run (and anything else routed through salt.utils.functools.call_function()) crashed with got multiple values for argument 'size' when a positional argument was passed for a target-function parameter that also has a default value:

$ salt-call state.single module.run foo 'test.rand_str=[999]'
[ERROR   ] 'test.rand_str' failed: rand_str() got multiple values for argument 'size'

Root cause: call_function() pre-seeds function_kwargs with every defaulted parameter's default value up front, then appends raw positional list items to function_args without removing the corresponding key from function_kwargs. A parameter satisfied positionally that also happens to have a default (e.g. size in test.rand_str) ended up passed both positionally and via its stale default keyword — a genuine TypeError-equivalent collision.

Fix: once function_args is finalized, strip any argspec.args entries already covered positionally out of function_kwargs before merging in explicit kwargs and dict-style keyword items from the args list. This keeps the "kwargs win last" and missing-argument validation semantics intact.

Test plan

  • Added test_call_function_positional_arg_with_default in tests/pytests/unit/states/test_module.py, reproducing the exact issue scenario.
  • pytest tests/pytests/unit/states/test_module.py -v — 24 passed.
  • pytest tests/pytests/unit/modules/test_mine.py -v (other caller of call_function) — 18 passed, no regressions.
  • Manually verified the fix against the reported repro shape (positional-only, positional+dict-kwarg, dict-kwarg-only, required-arg-missing-error cases).

🤖 Generated with Claude Code

@HarnageaGabriel
HarnageaGabriel requested a review from a team as a code owner August 18, 2026 19:45
…alues"

salt.utils.functools.call_function() pre-seeded function_kwargs with every
defaulted parameter's default value, then appended positionally-passed
values to function_args without removing the corresponding key from
function_kwargs. A parameter filled positionally that also has a default
(e.g. size in test.rand_str) ended up passed both positionally and as a
stale keyword default, raising "got multiple values for argument".

Strip argspec-matched keyword defaults from function_kwargs once
function_args is finalized, before merging in explicit kwargs.

Fixes saltstack#69919
@HarnageaGabriel
HarnageaGabriel force-pushed the fix-module-run-positional-default-arg branch from ebdb9d5 to ab6a576 Compare August 19, 2026 19:33
@twangboy twangboy added Tests test:full Run the full test suite and removed Tests labels Aug 21, 2026
@twangboy twangboy added this to the Argon v3008.3 milestone Aug 21, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

test:full Run the full test suite

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug]: module.run fails when passing positional args to parameters with defaults

2 participants