Skip to content

fix: a task or note never shows twice while its state changes - #110

Merged
pasichDev merged 2 commits into
migrate-to-kmpfrom
fix/duplicate-list-keys
Nov 10, 2026
Merged

pasichDev merged 2 commits into
migrate-to-kmpfrom
fix/duplicate-list-keys

Conversation

@pasichDev

Copy link
Copy Markdown
Owner

Merge order: into migrate-to-kmp before #92 is merged, so the fix ships in 3.0.0.

What and why

Play Console reports IllegalArgumentException: Key "2" was already used (and "3") from a LazyColumn. The cause is in 2.3.1 and in the 3.0.0 code.

  • Tasks: the screen combined two Room queries, one for open tasks and one for done tasks, into one state. When a task was checked or unchecked, one query could emit before the other, so for a moment the task was in both lists. Both lists are keyed by task id, so the list crashed. Both lists now come from one query (getAllTasks), split with partition. Done tasks are still sorted newest first.
  • A hidden tag's notes: the same race existed between the tag's live notes and its archived notes when a note was archived or unarchived. NotesDao.getArchivedNotesByTagId is replaced by getNotesOfTagWithArchived, one query, and the filter moves into ObserveNotesUseCase.

How it was tested

  • :shared:desktopTest for the tasks, notes list and repository tests (TasksViewModelTest 18/18), and :core:database:testAndroidHostTest (NotesDaoTest 19/19)
  • :core:database:updateKotlinAbi and :shared:updateKotlinAbi, dumps committed
  • Checked on a device / emulator

Not verified:

  • The new aTaskBeingCheckedOrUncheckedIsNeverInBothListsAtOnce test also passes without the fix. The test repository derives both lists from one StateFlow, so it cannot reproduce Room's separate query emissions. The fix comes from reading one query. The test only pins the behaviour.
  • The crash was not reproduced on a device.

Security and data checklist

  • No new permission, and in particular no INTERNET permission.
  • No network, analytics, telemetry or proprietary (Google Play Services) dependency.
  • No new path that puts plaintext outside the vault.
  • No change to key derivation, the SQLCipher passphrase, the vault slots or any on-disk format.
  • No Room schema change (a new query, no new table or column).
  • User-visible change is listed under 3.0.0 / Fixed in CHANGELOG.md.

The tasks screen read open and done tasks through two queries combined
into one state, so a task that was just checked or unchecked could sit
in both lists for a moment and the list crashed on the repeated key. A
hidden tag's view did the same with its live and archived notes. Each
list now comes from one query.
@pasichDev
pasichDev merged commit 2952e1c into migrate-to-kmp Nov 10, 2026
11 of 13 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant