Skip to content

[BUG]Crash: IllegalStateException when deleted note is queried as a non-null Note #369

@daxiami233

Description

@daxiami233

App Information

  • App name: Easy Notes
  • Package name: com.kin.easynotes
  • Version: 1.7-fdroid
  • Version code: 14
  • Issue type: Crash
  • Android version: 9.0

Expected Behavior

The app should remain stable when the user deletes a note from the note editing page.

After the user confirms deletion, the app should return to the note home page automatically, and the deleted note should be removed from the note list.

Actual Behavior

The app crashes during or immediately after the note deletion flow.

After the note is deleted, the app still attempts to query the deleted note as a required non-null Note object. Since the query result is empty, an uncaught IllegalStateException is thrown, and Android terminates the app process.

Reproduction Steps

  1. Launch Easy Notes.
  2. Open an existing note and enter the note editing page.
  3. Open the more-options menu.
  4. Tap the Delete menu item.
  5. Observe whether a delete confirmation dialog appears.
  6. Confirm the deletion.
  7. Observe whether the app returns to the note home page and whether the deleted note is removed from the list.
  8. The app crashes after the delete operation because the deleted note is queried as a non-null object.

Crash Log

05-22 14:09:10.817 E/AndroidRuntime( 9378): FATAL EXCEPTION: main
05-22 14:09:10.817 E/AndroidRuntime( 9378): Process: com.kin.easynotes, PID: 9378
05-22 14:09:10.817 E/AndroidRuntime( 9378): java.lang.IllegalStateException: The query result was empty, but expected a single row to return a NON-NULL object of type <com.kin.easynotes.domain.model.Note>.
05-22 14:09:10.817 E/AndroidRuntime( 9378):     at n3.b.k(r8-map-id-912d22bf732c793dd6ce0a61b7047cb26ee10a96c5724178ea06c7a01d102097:143)
05-22 14:09:10.817 E/AndroidRuntime( 9378):     at v2.d.s(r8-map-id-912d22bf732c793dd6ce0a61b7047cb26ee10a96c5724178ea06c7a01d102097:211)
05-22 14:09:10.817 E/AndroidRuntime( 9378):     at v2.d.i(r8-map-id-912d22bf732c793dd6ce0a61b7047cb26ee10a96c5724178ea06c7a01d102097:13)
05-22 14:09:10.817 E/AndroidRuntime( 9378):     at s2.b.g(r8-map-id-912d22bf732c793dd6ce0a61b7047cb26ee10a96c5724178ea06c7a01d102097:24)
05-22 14:09:10.817 E/AndroidRuntime( 9378):     at p2.t.r(r8-map-id-912d22bf732c793dd6ce0a61b7047cb26ee10a96c5724178ea06c7a01d102097:7)
05-22 14:09:10.817 E/AndroidRuntime( 9378):     at v2.b.s(r8-map-id-912d22bf732c793dd6ce0a61b7047cb26ee10a96c5724178ea06c7a01d102097:39)
05-22 14:09:10.817 E/AndroidRuntime( 9378):     at k4.a.g(r8-map-id-912d22bf732c793dd6ce0a61b7047cb26ee10a96c5724178ea06c7a01d102097:9)
05-22 14:09:10.817 E/AndroidRuntime( 9378):     at D4.L.run(r8-map-id-912d22bf732c793dd6ce0a61b7047cb26ee10a96c5724178ea06c7a01d102097:117)
05-22 14:09:10.817 E/AndroidRuntime( 9378):     at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167)
05-22 14:09:10.817 E/AndroidRuntime( 9378):     at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641)
05-22 14:09:10.817 E/AndroidRuntime( 9378):     at java.lang.Thread.run(Thread.java:764)
05-22 14:09:10.817 E/AndroidRuntime( 9378):     Suppressed: I4.g: [A0{Cancelling}@65c9dc1, Dispatchers.Main.immediate]
05-22 14:09:10.820 W/ActivityManager( 1609): Force finishing activity com.kin.easynotes/.presentation.MainActivity
05-22 14:09:10.873 W/InputDispatcher( 1609): channel 'f5ca875 com.kin.easynotes/com.kin.easynotes.presentation.MainActivity (server)' ~ Consumer closed input channel or an error occurred. events=0x9
05-22 14:09:10.873 E/InputDispatcher( 1609): channel 'f5ca875 com.kin.easynotes/com.kin.easynotes.presentation.MainActivity (server)' ~ Channel is unrecoverably broken and will be disposed!
05-22 14:09:10.874 I/WindowManager( 1609): WIN DEATH: Window{f5ca875 u0 com.kin.easynotes/com.kin.easynotes.presentation.MainActivity}
05-22 14:09:10.874 W/InputDispatcher( 1609): Attempted to unregister already unregistered input channel 'f5ca875 com.kin.easynotes/com.kin.easynotes.presentation.MainActivity (server)'
05-22 14:09:10.884 I/ActivityManager( 1609): Process com.kin.easynotes (pid 9378) has died: vis +99TOP
05-22 14:09:10.886 W/SurfaceFlinger( 1467): Attempting to set client state on removed layer: com.kin.easynotes/com.kin.easynotes.presentation.MainActivity#0
05-22 14:09:10.886 W/SurfaceFlinger( 1467): Attempting to destroy on removed layer: com.kin.easynotes/com.kin.easynotes.presentation.MainActivity#0

Analysis

The crash is caused by a database query that expects exactly one non-null note object, but the query returns no rows:

java.lang.IllegalStateException:
The query result was empty, but expected a single row to return a NON-NULL object of type <com.kin.easynotes.domain.model.Note>.

This is typical of a Room DAO or repository method whose return type is declared as a non-null Note, while the database state can legally contain no matching row.

The visible trigger is the note deletion flow:

Open note editing page
Open more menu
Tap Delete
Confirm deletion

After the note is deleted, the app should navigate away from the editing page and stop observing or querying that deleted note. However, the stack trace indicates that the app still performs a query for the same note and expects a non-null result.

The relevant stack trace includes the app/database flow before the exception reaches the coroutine execution path:

n3.b.k
v2.d.s
v2.d.i
s2.b.g
p2.t.r
v2.b.s
k4.a.g
D4.L.run

The suppressed coroutine context shows that this failure is associated with a main-dispatcher coroutine:

Suppressed: I4.g: [A0{Cancelling}@65c9dc1, Dispatchers.Main.immediate]

This means the empty query result is not handled as a normal post-deletion state. Instead, it propagates as an uncaught exception, causing Android to force-finish the main activity:

Force finishing activity com.kin.easynotes/.presentation.MainActivity
Process com.kin.easynotes (pid 9378) has died

The root cause is that the app treats a note record as always existing even after the user deletes it. The delete flow should handle the empty result case or navigate away before continuing to observe/query the deleted note.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions