Skip to content

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

Open
ggiesen wants to merge 1 commit into
saltstack:3006.xfrom
ggiesen:fix-53692-61042
Open

Fix TypeError in file.recurse/directory clean when a require ID contains "file"#69760
ggiesen wants to merge 1 commit 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
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.

3 participants