Invalidate stale rule caches missing bytes_prefix_index#3116
Conversation
Bump cache format to v2 and reject cached rulesets whose feature index schema is outdated, instead of crashing at match time with AttributeError. Fixes mandiant#2961
There was a problem hiding this comment.
Please add bug fixes, new features, breaking changes and anything else you think is worthwhile mentioning to the master (unreleased) section of CHANGELOG.md. If no CHANGELOG update is needed add the following to the PR description: [x] No CHANGELOG update needed
There was a problem hiding this comment.
Code Review
This pull request updates the rule cache mechanism to handle outdated internal schemas by incrementing the cache version, expanding exception handling during cache loading, and introducing a validation check to ensure the cached ruleset contains the required attributes. Feedback suggests safely accessing the _feature_indexes_by_scopes attribute using getattr to prevent potential AttributeError crashes, as this check is performed outside the main try-except block.
Important
The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.
| for feature_index in ruleset._feature_indexes_by_scopes.values(): | ||
| if not hasattr(feature_index, "bytes_prefix_index"): | ||
| return False |
There was a problem hiding this comment.
If the unpickled ruleset is from an older cache version or is corrupted, it might not have the _feature_indexes_by_scopes attribute. Accessing it directly will raise an AttributeError and crash the application, as this call is outside the try-except block in load_cached_ruleset. Using getattr to safely retrieve the attribute prevents potential crashes.
| for feature_index in ruleset._feature_indexes_by_scopes.values(): | |
| if not hasattr(feature_index, "bytes_prefix_index"): | |
| return False | |
| feature_indexes = getattr(ruleset, "_feature_indexes_by_scopes", None) | |
| if feature_indexes is None: | |
| return False | |
| for feature_index in feature_indexes.values(): | |
| if not hasattr(feature_index, "bytes_prefix_index"): | |
| return False |
Avoid AttributeError when unpickled rulesets lack _feature_indexes_by_scopes.
|
@itxsamad1 would you please explain the sequence of events that led to you encountering this issue? i'm surprised that the caching logic doesn't already notice this. |
Summary
Fixes runtime crashes when loading stale rule caches whose pickled
_RuleFeatureIndexobjects predate thebytes_prefix_indexfield (#2961).Fixes #2961
Test plan
pytest tests/test_rule_cache.py(5 passed)test_ruleset_cache_rejects_outdated_schemasimulating pre-bytes_prefix_indexindex objects