Skip to content

[Tune] Fix duplicate wrapper state key check in SearchGenerator.save_to_dir - #68153

Open
deep1blue wants to merge 2 commits into
ray-project:masterfrom
deep1blue:fix/tune-search-generator-duplicate-state-key
Open

deep1blue wants to merge 2 commits into
ray-project:masterfrom
deep1blue:fix/tune-search-generator-duplicate-state-key

Conversation

@deep1blue

@deep1blue deep1blue commented Nov 14, 2026 •

Copy link
Copy Markdown
Contributor

Why are these changes needed?

In SearchGenerator.save_to_dir (python/ray/tune/search/search_generator.py), wrapper searcher state is stored in search_alg_state under the "name:"-prefixed key (search_alg_state["name:" + searcher_name] = searcher.get_state()) and restored in restore_from_dir using searcher_name = "name:" + type(searcher).__name__.

However, the duplicate check in save_to_dir previously checked if searcher_name in search_alg_state: without the "name:" prefix. Because keys in search_alg_state are prefixed with "name:", this check always evaluated to False:

  1. The duplicate wrapper warning ("There was a duplicate when saving ... Restore may not work properly.") was never logged.
  2. Any inner wrapper of the same class overwrote search_alg_state["name:" + searcher_name], causing restore_from_dir to restore the inner wrapper's state into the outer wrapper.

This PR checks state_key = f"name:{searcher_name}" against search_alg_state in save_to_dir so duplicates are properly detected and the outer wrapper state is preserved.

Acknowledgments

Thanks to the Ray Tune maintainers and contributors who designed SearchGenerator and its wrapper state serialization (Repeater, ConcurrencyLimiter), and to @gemini-code-assist[bot] and @cursor[bot] for suggesting the f-string warning, propagate_logs fixture, and inner-wrapper state assertion.

Checks

  • I've signed off every commit (by: Parth Vadera <parthvadera@gmail.com>)
  • Added unit test test_search_generator_duplicate_wrapper_save_restore in python/ray/tune/tests/test_searcher_utils.py.

…to_dir

Check `f"name:{searcher_name}" in search_alg_state` when saving nested search wrappers in `SearchGenerator.save_to_dir`, matching the `"name:"` prefix used when storing keys in `save_to_dir` and reading them in `restore_from_dir`. Previously, the unprefixed check always evaluated to `False`, suppressing the duplicate wrapper warning and overwriting the outer wrapper's saved state.

Signed-off-by: Parth Vadera <parthvadera@gmail.com>
@deep1blue
deep1blue requested a review from a team as a code owner November 14, 2026 00:57

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request fixes a bug in SearchGenerator.save_to_dir where duplicate searcher states were not correctly identified due to a mismatch between the checked key and the saved key. This is resolved by introducing a consistent state_key variable. Additionally, a unit test is added to verify the save and restore behavior of nested searcher wrappers. The review feedback suggests using an f-string for the warning logger to maintain consistency and adding an assertion to the new test to verify that the inner wrapper's state is not incorrectly overwritten.

Comment on lines 177 to 180
logger.warning(
"There was a duplicate when saving {}. "
"Restore may not work properly.".format(searcher_name)
)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

Since an f-string is already used on line 175 to construct state_key, we should also use an f-string here for the warning message to maintain consistency and improve readability.

Suggested change
logger.warning(
"There was a duplicate when saving {}. "
"Restore may not work properly.".format(searcher_name)
)
logger.warning(
f"There was a duplicate when saving {searcher_name}. "
"Restore may not work properly."
)

)
restored_alg = SearchGenerator(restored_outer)
restored_alg.restore_from_dir(str(tmp_path))
assert restored_outer.repeat == 2

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

To make this test more robust and explicitly verify that the inner repeater's state was not incorrectly overwritten or restored with the outer repeater's state, we should also assert that the inner repeater's repeat value remains unchanged (i.e., 1).

Suggested change
assert restored_outer.repeat == 2
assert restored_outer.repeat == 2
assert restored_outer.searcher.repeat == 1

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes using default effort and found 1 potential issue.

Fix All in Cursor

Reviewed by Cursor Bugbot for commit d16e500. Configure here.

@ray-gardener ray-gardener Bot added tune Tune-related issues community-contribution Contributed by the community labels Nov 14, 2026
Use an f-string for the duplicate wrapper warning in SearchGenerator.save_to_dir, add the propagate_logs fixture to test_search_generator_duplicate_wrapper_save_restore, and assert that the inner repeater state is preserved on restore.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Signed-off-by: Parth Vadera <parthvadera@gmail.com>

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

community-contribution Contributed by the community tune Tune-related issues

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant