Device App cannot be relaunched via Complication Press after being killed by Power Save Timeout

Hi everyone,
I am developing a Device App (built with Connect IQ SDK 4.2+ / API level 5.0.0) that registers and publishes data to two native/third-party watch face complication slots using Complications.updateComplication().
I am encountering a strange lifecycle / routing freeze bug regarding how the app is exited. Here are the two distinct scenarios:
  • Scenario A (Normal Exit - Works): If the user opens the Device App, interacts with it, and manually exits back to the watch face, clicking the complication on the watch face successfully launches the app as expected.
  • Scenario B (Power Save Kill - Breaks): If the user opens the Device App and leaves it unattended in the foreground until the screen dims and the system forces a Power Save Timeout (Hard Kill), the complication on the watch face completely freezes its click behavior. Clicking the complication fails to launch the app, rendering the slot unresponsive until the app is manually opened through the activities menu again.
Our Current Findings:
We suspect the issue is inside the onStop(state) lifecycle method. Currently, the app invokes Complications.updateComplication() inside onStop() on every exit path to ensure the watch face receives the last-cached values.
When Scenario B happens, the foreground UI thread is being torn down by the OS while simultaneously attempting to open an IPC pipe to the system's complication manager during onStop(). This seems to corrupt the underlying routing table, causing the Garmin OS to flag the App ID as "zombie/suspended" rather than fully deceased. Thus, subsequent watch face click events are intercepted or ignored by the OS instead of triggering a clean Cold Start.
Questions:
  1. Has anyone else experienced a breakdown of Complication click-to-launch routing when a Device App is terminated by a screen-off timeout?
  2. Is skipping the complication publication explicitly inside the foreground onStop() path the recommended way to avoid this deadlock, or is there a specific state flag passed into onStop(state) that can help differentiate a clean user-exit from a forced system power-save shutdown?
Any insights or architectural advice would be greatly appreciated!
Thanks in advance.

  • Have you tried adding println calls to help track what's happening on the real device?

    If you are using the 4.2 SDK, it's really old.  9.3.0 is the latest.

  • I haven't  I've been focused on narrowing down the codebase, but I can set that up.However, looking strictly at the lifecycle flow, here is exactly what my onStop() looks like:
    function onStop(state as Dictionary?) as Void {
        armBackgroundRefresh();
        try {
            // This is shared by both foreground exit and background process termination
            TeaTimeComplications.publish(); 
        } catch (e) {
        }
    }
    
    The publish() function internally executes Complications.updateComplication().
    My main suspicion is that during a forced Power Save Timeout, the foreground process tree is in the middle of being dismantled by the OS. Executing an IPC call like updateComplication() right at this collapsing moment might be corrupting the OS complication routing table, leaving the watch face with a "zombie" reference to the app.
    Before I jump into logs, is it generally considered unsafe or an anti-pattern to push complication updates inside a foreground onStop() during a system-enforced shutdown?