Skip to content

Fix TypeError in file.recurse/directory clean when a require ID contains "file" - #69760

Merged
dwoz merged 2 commits into
saltstack:3006.xfrom
ggiesen:fix-53692-61042
Aug 4, 2026
Merged

Fix TypeError in file.recurse/directory clean when a require ID contains "file"#69760
dwoz merged 2 commits into
saltstack:3006.xfrom
ggiesen:fix-53692-61042

Conversation

@ggiesen

@ggiesen ggiesen commented Jul 10, 2026

Copy link
Copy Markdown
Contributor

What does this PR do?

Guards the requisite filter in _gen_keep_files() (salt/states/file.py) with an isinstance(comp, dict) check so it only inspects dict-form requisites.

The filter was required_files = [comp for comp in require if "file" in comp]. For a bare-string requisite ID (written as - some_id rather than - file: some_id), "file" in comp degrades from a dict-key check into a substring test, so any ID containing the substring "file" (e.g. aaa_file, p_files_recurse_test_recurse_one) slips through. The loop then evaluates comp["file"] on a str and raises TypeError: string indices must be integers. The crash only fires when __lowstate__ is non-empty.

What issues does this PR fix or reference?

Fixes #53692
Fixes #61042

Previous Behavior

file.recurse / file.directory run with clean: True crashed with TypeError: string indices must be integers whenever a require requisite was a bare state ID string whose ID contained the substring "file".

New Behavior

Bare-string requisites are ignored by the keep-files filter instead of crashing. Normal dict requisites (- file: <id>), which are the supported way to retain a required state's files during a clean, are unaffected and still contribute their files to the keep list.

Merge requirements satisfied?

[NOTICE] Bug fixes or features added to Salt require tests.

  • Docs - n/a (no user-facing docs change; behaviour is a bug fix)
  • Changelog - changelog/53692.fixed.md and changelog/61042.fixed.md
  • Tests written/updated - added to tests/pytests/unit/states/file/test_find_keep_files.py: direct-altitude regression tests for both issues (bare-string ID containing "file" must return [], not raise), inverse must-not-regress tests proving dict requisites still retain their files, and peripheral coverage confirming a bare ID without "file" stays silently dropped.

Commits signed with GPG?

No

_gen_keep_files filtered requisites with `"file" in comp`, which for a
bare-string requisite ID degraded to a substring match. Any ID containing
the substring "file" then hit `comp["file"]` and raised
"TypeError: string indices must be integers". Guard the membership test
with an isinstance check so only dict requisites are considered; bare
strings are ignored instead of crashing.

Fixes saltstack#53692 and Fixes saltstack#61042
@charzl charzl self-assigned this Jul 10, 2026
@dwoz dwoz added the test:full Run the full test suite label Jul 10, 2026
Comment thread salt/states/file.py
@twangboy twangboy added this to the Sulphur v3006.28 milestone Jul 15, 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.

5 participants