fix(ui): prevent duplicate LazyColumn keys in node metrics logs#5890
Merged
Conversation
Several node-detail metrics log lists keyed their LazyColumn items on a
bare second-resolution timestamp (telemetry.time / position.time). When a
node delivers two telemetry or position packets within the same second
(bursts, resends), two items share a key and Compose throws
IllegalArgumentException: "Key ... was already used", crashing the
metrics screens (seen on the 2.8.0 internal track, versionCode 29321164).
Give every item a guaranteed-unique key, matching the existing
HostMetricsLog pattern:
- Device, Environment, Power, Air Quality, and Position logs now key on
"${time}_$index" instead of the bare timestamp.
- SignalMetrics.LocalStatsEntry had the same bare-timestamp defect; it now
threads the source-list index ("local_stats_${time}_$index"), keeping
the sibling PacketEntry's real packet-id key intact.
This standardizes the whole node-metrics module on two key patterns: a
real unique id (uuid / packet id) where the element carries one, and
"${time}_$index" for the id-less Telemetry/Position protos.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
The node-detail metrics screens crash with
IllegalArgumentException: Key "<timestamp>" was already usedwhen a node reports two telemetry or position samples in the same wall-clock second. SeveralLazyColumns keyed their items on a bare second-resolution timestamp, so same-second samples collide and Compose tears the screen down. Observed on the 2.8.0 internal track (versionCode 29321164); the crash recurs across versions.🐛 Bug Fixes
LazyColumnitem a guaranteed-unique key. The Device, Environment, Power, Air Quality, and Position logs now key on"${time}_$index"(the patternHostMetricsLogalready used) instead of the baretelemetry.time/position.time.SignalMetrics.LocalStatsEntry(its key was"local_stats_${time}"); it now threads the source-list index so two local-stats samples in the same second can't collide. The siblingPacketEntrykeeps its real packet-id key ("packet_${meshPacket.id}").🛠️ Refactoring & Architecture
feature/nodemetrics module on two patterns: a real unique id (uuid/ packetid) where the list element carries one, and"${time}_$index"for the id-lessTelemetry/Positionprotos. No bare-timestamp keys remain.Why not a real id everywhere?
The data layer does have a unique id for every one of these lists (each
Telemetryis parsed from aMeshLogwith auuid; positions come from aMeshPacketwith.id), but those ids are discarded when the rows are mapped to bare protos before reaching the UI state. Threading them through to a singlekey = { it.uuid }idiom would be a data-model refactor (changingMetricsState's list types and rippling through the use case, charts, and CSV exporters), so it's out of scope for this crash fix and noted as a possible follow-up.Testing Performed
./gradlew spotlessApply spotlessCheck detekt :feature:node:allTests kmpSmokeCompile— all green (722 tests pass; Spotless and detekt clean).