fix(favorites): version-key supportsFavorites cache so it can't stick on unsupported#3482
Conversation
… on "unsupported" Auto Favorites warned "Firmware 2.7.24 does not support favorites (requires >= 2.7.0)" on firmware that clearly qualifies. The version math is correct; the bug is a stale cache. supportsFavorites() cached its result in a bare boolean, and cached `false` whenever it ran before the firmware version was known (localNodeInfo.firmwareVersion starts null until DeviceMetadata). The version then reaches localNodeInfo through NodeInfo/node-rebuild paths that do NOT clear favoritesSupportCache (only processDeviceMetadata does), so on reconnect — where the DB already has the version — the cached `false` stuck even though firmwareVersion read "2.7.24". Fix: key the cache by the firmware version it was computed from, and never cache the unknown-firmware case. A cache hit is served only when it matches the current firmware version, so a `false` computed while the version was unknown is recomputed as soon as the version is populated by any path. Robust to event ordering without sprinkling cache-clears across the rebuild sites. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|
Claude encountered an error —— View job I'll analyze this and get back to you. |
|
Claude finished @Yeraze's task —— View job PR Review Complete ✅Todo List:
Code Quality: Excellent 👍The implementation is clean, well-documented, and follows established patterns in the codebase. The change from a bare boolean cache to a version-keyed cache structure is elegant and solves the root cause rather than applying band-aid fixes. Key Strengths:
Technical Review:Cache Logic (meshtasticManager.ts:12102-12104): if (this.favoritesSupportCache?.version === firmwareVersion) {
return this.favoritesSupportCache.result;
}✅ Correct: Cache hit only when version matches current firmware, ensuring stale results are impossible. Edge Case Handling:
Performance Considerations: Good ⚡
Security Considerations: No Issues 🔒
Potential Improvements (Minor):
interface FavoritesSupportCache {
version: string;
result: boolean;
}
private favoritesSupportCache: FavoritesSupportCache | null = null;
Test Coverage: Comprehensive 🧪The test suite covers all critical scenarios including the exact regression from the bug report. The use of mocks is appropriate and the test structure is clean. Verdict: LGTM ✅This is a high-quality fix that:
The version-keyed caching strategy is robust and will prevent similar issues in the future. |
Bump version to 4.10.4 across package.json, package-lock.json, helm/meshmonitor/Chart.yaml, desktop/package.json, and desktop/src-tauri/tauri.conf.json. Promote CHANGELOG [Unreleased] to [4.10.4] and add the user-facing fixes merged since 4.10.3: timed-events cross-source firing (#3479), module config save for Traffic Management/Status Message (#3464), Auto Favorites firmware-support cache (#3482), MeshCore Share Contact error surfacing (#3481), and the Firefox-Android delivered-icon CSS fix (#3477). The air-quality particle-count fix (#3483) was already in [Unreleased]. Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Summary
Users on firmware 2.7.24 saw Auto Favorites warn "Firmware 2.7.24 does not support favorites (requires >= 2.7.0)" — a contradiction. The version math is correct (
2.7.24→ minor ≥ 7 → supported); the bug is a stale cache.supportsFavorites()cached its result in a bare boolean and cachedfalsewhenever it ran before the firmware version was known (localNodeInfo.firmwareVersionstartsnulluntil DeviceMetadata arrives). The version then reacheslocalNodeInfothrough NodeInfo/node-rebuild paths (:4307,:4342,:4417) that do not clearfavoritesSupportCache— onlyprocessDeviceMetadatadoes. So on reconnect, where the DB already holds the version, the cachedfalsestuck even thoughfirmwareVersionread"2.7.24".This is the same family as the Traffic Management gate bug (#3457) but a different mechanism — favorites is the one check with a sticky cache;
firmwareVersionAtLeast()(Traffic Management / StatusMessage) reads the version fresh each call and is immune.Changes
favoritesSupportCacheis now version-keyed ({ version, result }) instead of a bare boolean.supportsFavorites()returnsfalsefor unknown firmware without caching it, and serves a cache hit only when it matches the current firmware version — recomputing otherwise. Robust to event ordering and to which path populates the version, without sprinkling cache-clears across the rebuild sites.:1616/:1629/:4920) remain valid and unchanged.Issues Resolved
Resolves the user report: Auto Favorites showing "firmware not new enough" on 2.7.24.
Documentation Updates
No documentation changes needed — internal caching logic.
Testing
tsc --noEmit)meshtasticManager.favoritesSupport.test.ts(7): 2.7.24 (incl. git suffix), pre-2.7.0, unknown-firmware-not-cached, the poison-then-repopulate regression, version-boundary recompute, and cache-by-versionpassiveModeandautoFavoritesuites still green with the new cache shape🤖 Generated with Claude Code