From 2c80be32443e3502512958679cb4c6300ee3ad5c Mon Sep 17 00:00:00 2001 From: Strycher Date: Mon, 20 Jul 2026 04:09:08 -0400 Subject: [PATCH] fix(#333): load channels before channel history, or history reads empty Channel history is keyed by the channel's PSK (#194), and the resolver set on the store reads that PSK out of _channels. After SELF_INFO, loadCachedChannels() and loadAllChannelMessages() were both fired without awaiting, so the messages could load while _channels was still empty. The resolver then returned null, _storageKey() silently fell back to the legacy slot-index key, and channels read as empty even though their history was intact under the PSK key. Silent because the fallback is a legitimate code path: there is no error, no parse failure and no log line, just an empty list. It is indistinguishable from data loss to the user. Observed on a live radio: Public held 566 messages under channel_messages_psk_8b3387e9..., and the app displayed nothing. loadAllChannelMessages() now runs only after loadCachedChannels() completes. The startup call in main.dart already awaits in the right order; it runs before any radio is connected, which is the source of the "Public key hex is not set" warnings at launch, and is harmless once this post-connect load is correct. Was previously committed against #291 on the nav-redesign branch; split out here under its own issue. --- lib/connector/meshcore_connector.dart | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/lib/connector/meshcore_connector.dart b/lib/connector/meshcore_connector.dart index 04cbbbf..a27c2f4 100644 --- a/lib/connector/meshcore_connector.dart +++ b/lib/connector/meshcore_connector.dart @@ -4646,10 +4646,14 @@ class MeshCoreConnector extends ChangeNotifier { _loadChannelOrder(); loadContactCache(); loadChannelSettings(); - loadCachedChannels(); - // Load persisted channel messages - loadAllChannelMessages(); + // Channel history is keyed by the channel's PSK (#194), and the resolver + // set above reads that PSK out of _channels. So the channel list MUST be + // loaded before the messages are: loading them concurrently leaves the + // resolver returning null, _storageKey() silently falls back to the legacy + // slot-index key, and every channel reads as empty even though its history + // is intact under the PSK key. + unawaited(loadCachedChannels().then((_) => loadAllChannelMessages())); loadUnreadState(); _loadDiscoveredContactCache();