Skip to content

fix(mobile): stop false "task failed" notifications for stale/cancelled runs#2462

Draft
k11kirky wants to merge 1 commit into
mainfrom
posthog-code/mobile-no-false-task-failed-notifications
Draft

fix(mobile): stop false "task failed" notifications for stale/cancelled runs#2462
k11kirky wants to merge 1 commit into
mainfrom
posthog-code/mobile-no-false-task-failed-notifications

Conversation

@k11kirky
Copy link
Copy Markdown
Contributor

@k11kirky k11kirky commented Jun 2, 2026

Problem

As a user of both the desktop and mobile apps, you frequently get "XYZ failed" push notifications from mobile for tasks that are stale with no activity — tasks that didn't fail, you'd simply finished with them.

The "XYZ failed" body is produced in taskSessionStore.maybePresentLocalNotification, fired from the terminal-status branch of _handleCloudUpdate. Two design choices combined to cause false alerts:

  1. cancelled was mislabeled as failed. mapTerminalStatus collapsed the backend cancelled status into failed. When a cloud sandbox is stopped/reaped after you finish with a task, the run goes cancelled — and the app showed "Run failed" and pushed "XYZ failed". (A genuine user cancel mid-turn comes back as _posthog/turn_complete, so cancelled as a run status overwhelmingly means "stopped", not "failed".)

  2. Stale reconnects re-fired the notification. By design, snapshots don't clear awaitingPing so the terminal-status block can own the terminal ping. But it didn't distinguish recent from long-ago: reconnecting to a run that ended while you were away, with awaitingPing still armed from your last prompt, re-fired "XYZ failed" for something you finished with hours earlier.

Changes

  • mapTerminalStatus keeps cancelled as a distinct terminal state instead of collapsing it into failed. Cancelled runs now show a neutral "Run stopped" banner (success styling, "Continue" action) and never fire a failure notification.
  • Thread the run's updated_at (already tracked as watcher.lastStatusUpdatedAt) through status/snapshot updates as statusUpdatedAt, and suppress the terminal ping when the transition is older than 2 minutes. A missing/unparseable timestamp is treated as fresh, so genuine just-happened terminal alerts are never suppressed.
  • The live logs path (a _posthog/error arriving while you're actively waiting) is unchanged — that's a real, just-happened failure and still notifies.
  • Extracted the terminal banner into a small TerminalStatusBanner component to cleanly handle the three states.

Frontend behavior change (no screenshot — node/vitest env): cancelled runs render "Run stopped" instead of "Run failed".

How did you test this?

  • Added taskSessionStore.test.ts (5 cases): no ping for a cancelled run, ping for a recent failed run, no ping for a stale failed run (reconnect snapshot), no ping when not awaiting a ping, and a completion ping. All pass.
  • npx vitest run src/features/tasks → 20 files / 75 tests pass.
  • npx tsc --noEmit clean for all changed source files; biome check clean on changed files. (Pre-existing, unrelated tsc errors remain from test-infra typings and the unbuilt @posthog/shared package.)

Automatic notifications

  • Publish to changelog?
  • Alert Sales and Marketing teams?

Created with PostHog Code

…ed runs

Mobile fired "<task> failed" notifications for tasks the user had simply
finished with. Two causes:

1. mapTerminalStatus collapsed the backend "cancelled" status into "failed".
   A cancelled run (sandbox stopped / user finished) is a normal lifecycle
   end, not a failure, but it was surfaced as "Run failed" and pushed a
   "<task> failed" notification. Cancelled is now a distinct terminal state
   ("Run stopped") and never pings as a failure.

2. The terminal-status notification fired on stale reconnects. awaitingPing
   is deliberately preserved across snapshots, so reconnecting to a run that
   ended (failed/cancelled) while the device was away re-fired a terminal
   notification for a run the user had already moved on from. We now thread
   the run's updated_at through status/snapshot updates and suppress the ping
   when the terminal transition is older than 2 minutes (missing timestamp is
   treated as fresh, so genuine just-happened alerts are never suppressed).

Adds taskSessionStore.test.ts covering: no ping for cancelled, ping for a
recent failure, no ping for a stale failure, no ping when not awaiting, and a
completion ping.

Generated-By: PostHog Code
Task-Id: 8bca0c4c-ff31-41f6-9f20-0fd2a4e91860
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