Repository navigation
[Bug]: An ended iOS Live Activity stays frozen on the Lock Screen when the app opens with no work running #16241
Description
Area
apps/mobile
Summary
#15254 dismisses ended Live Activities, but only inside LiveActivityFactory.start(), so only when the app creates a new card. Opening the app with no agent work running never calls start(). A card that iOS has already ended therefore stays frozen on the Lock Screen, and the app has no way to see it. #12656 handled this on every foreground. It was closed as superseded by #15254, but #15254 kept only the dismiss-before-start part.
Steps to reproduce
- iPhone, T3 Connect linked, Live Activity Updates on. Keep one card in use long enough for iOS to end it. Done is sent as an update, not an end, so one card is reused from turn to turn and can reach the ~8-hour limit in normal use. fix(mobile): an expired Live Activity no longer leaves a second card #15254's simulator method (end card A with the default dismissal policy) reproduces the ended state without the 8-hour wait.
- The card disappears from the Dynamic Island but stays on the Lock Screen showing its last content.
- Open T3 Code while no agent work is running on any linked environment, then lock the phone.
Expected behavior
Opening the app dismisses the ended card. A new card is armed the next time work runs, as it is today.
Actual behavior
The ended card stays on the Lock Screen for up to 4 hours, showing stale content that can no longer be updated. Opening the app any number of times doesn't remove it. Only swiping it away, or opening the app while a turn is running (which goes through start()), clears it.
Observed on a real iPhone: a frozen "Done" card on the Lock Screen, absent from the Dynamic Island when unlocked. New turns were arriving as plain push notifications instead of card updates, and reopening the app didn't change that. After swiping the card away, the next turn armed a fresh card and updates resumed. I didn't inspect the activity state on the device, so the ~8-hour limit is the most likely cause, not a confirmed one.
Root cause (main @ 25d5c7c)
getInstances()inexpo-widgetsonly returns.activeand.staleactivities ([ios][widgets] Fix Live Activity getInstances() filtering and start URL scoping expo/expo#48489). The foreground reconcile inapps/mobile/src/features/agent-awareness/remoteRegistration.ts(getAgentLiveActivities()at line 1084) never sees an ended card.- The only dismissal of ended cards is in
LiveActivityFactory.start()inpatches/expo-widgets@58.0.11.patch(line 28, from fix(mobile): an expired Live Activity no longer leaves a second card #15254). - The reconcile only calls
start()when no card is visible and the relay snapshot hasactiveCount > 0(remoteRegistration.ts:1117,:1138). An idle open skips it.
Suggested fix
Move the ended-card loop from start() into its own factory method in the expo-widgets patch (for example dismissEnded(), still scoped to the factory's name). Call it at the top of the foreground reconcile, before getAgentLiveActivities(), and keep calling it from start(). This restores the foreground half of #12656, which already had tests for this path. Like #15254, it needs a store build.
Related
- fix(mobile): dismiss ended Live Activities on foreground #12656: the original foreground dismissal, closed as superseded.
- fix(mobile): an expired Live Activity no longer leaves a second card #15254: dismiss-before-start only.
- [Bug]: iOS Live Activity keeps showing "T3 Done" for hours when no other agent event arrives #11939, [Bug]: iOS Live Activity keeps showing "Done" after you open the finished thread #15728, [Bug]: Settling a finished thread doesn't remove it from the iOS Live Activity #16229: Done cards that are never ended or removed stay alive long enough to reach the iOS limit.
Workaround
Swipe the card away on the Lock Screen, or open the app while a turn is running.
Version or commit
main @ 25d5c7c
Activity
juliusmarminge commentedon Oct 5, 2026
Note
Grok responding on behalf of Julius.
Triage
Thanks again, @jlipworth! The pointers to #15254, #12656 and the upstream
getInstances()change made this quick to trace.What I found
getInstances()return only.activeand.staleactivities, so an ended card that iOS still shows on the Lock Screen isn't in that list.getAgentLiveActivities()inapps/mobile/src/features/agent-awareness/agentLiveActivity.ios.tsis that call.expo-widgets@58.0.11patch dismisses this factory's.endedactivities only insideLiveActivityFactory.start(), right beforeActivity.request. Nothing else enumeratesActivity.activities.refreshActiveLiveActivityRemoteRegistrationinremoteRegistration.ts) callsstartAgentLiveActivityonly whengetAgentLiveActivities()is empty and the relay snapshot hasactiveCount > 0. Opening the app with no running work never reachesstart(), so the ended card stays.armAgentAwarenessLiveActivityForLocalWorkNow), does go throughstart(), which is why the card clears in those cases. Swiping the card away also works as a stopgap.endLocalLiveActivitiesonly ends whatgetInstances()returns.Likely fix area
dismissEnded()in theexpo-widgets@58.0.11patch (still filtered bycontent.state.nameand.ended, using.immediatedismissal), called at the top ofrefreshActiveLiveActivityRemoteRegistrationbeforegetAgentLiveActivities(), kept instart(), and reused inendLocalLiveActivities.patches/, so an OTA wouldn't ship the native method. fix(mobile): dismiss ended Live Activities on foreground #12656's cleanup-before-discovery tests may be reusable.A maintainer will decide on the fix direction.