[Bug]: Completion notifications never appear on Windows: 73-character notification tag exceeds the platform tag limit
Nobody has claimed this yet.
- Dominant language
- TypeScript
- Stars
- 23k
- Forks
- 5.9k
- Avg merge
- 11h 14m
- Merged PRs (30d)
- 357
Description
Environment
- T3 Code
0.0.42stable (desktop, Windows install; verified fromresources/app.asarand the exe version) - Electron
44.1.0(Chrome152.0.7977.65) - Windows 11 25H2, build
26200.9457 - Backend in WSL2 (Ubuntu), client served to the desktop window via
t3code://app - Notification mode
notifications-and-sound(inAppNotificationsEnabled: false)
Summary
When a turn completes while the desktop window is minimized or unfocused, Windows never shows the toast. The app still plays the notification sound and sets the red dot on the taskbar icon, and the Action Center stays empty.
The cause is the notification tag length. The coordinator builds (ThreadNotificationCoordinator.tsx:181):
tag: `${environmentId}:${thread.id}`
Both IDs are UUIDs, so the tag is 36 + 1 + 36 = 73 characters. On Windows, Chromium silently drops renderer notifications when the tag exceeds a platform limit, and the budget is shared with the origin, so the threshold varies per app and Electron version. The Notification constructor still succeeds and no error event fires, which is why the app-side effects (sound, taskbar badge) still happen while the toast never appears.
Steps to reproduce
- Settings -> General -> Thread notifications: choose a mode that includes notifications.
- Minimize the T3 Code window (or focus another app).
- Send a message to an agent and let the turn finish.
Expected
A Windows toast appears and lands in the Action Center.
Actual
Sound plays, the red dot appears on the taskbar icon, no toast, nothing in the Action Center, and LastNotificationAddedTime for com.t3tools.t3code never advances.
Evidence
Reproduced with a minimal Electron 44.1.0 app that mirrors T3's setup: scheme t3code with the same registerSchemesAsPrivileged privileges and host app, the same AppUserModelID (com.t3tools.t3code), silent: true, title "Thread completed", a real thread title as the body, and the window minimized. Checked two ways: the renderer's show event and Windows' own notification database (wpndatabase.db).
| tag | length | delivered |
|---|---|---|
control1 |
8 | yes (show fired, DB row) |
<threadId> alone |
36 | yes |
<envUuidPrefix>:<threadId> |
45 | yes |
<envUuid>:<threadId> (the actual format) |
73 | no (no show, no DB row) |
Boundary measurement with a slightly longer origin (repro-app://app): 46-character tags deliver, 47 and up are dropped. With T3's shorter origin (t3code://app), 45 delivers and 73 drops. The threshold moving with the origin matches Electron's behavior where the Windows toast tag is derived from a notification ID that includes the origin.
On the affected machine, the Windows notification database has no row from the main window origin at all. Every T3 notification that ever arrived had a short tag (manual test notifications created from a preview pane). The app-side creation path is confirmed to run: the taskbar badge is only set after new Notification(...) succeeds.
Related: electron/electron#40433 ("Windows 11 web notifications don't work when tag length is greater than 34") and electron/electron#42239, an attempted fix that hashes the tag. Still reproducible on Electron 44.1.0.
Suggested fix
Keep the tag short:
thread.idalone (36 characters, thread IDs are already unique), or- a short digest of
${environmentId}:${thread.id}(for example 16 hex characters)
Both the 36 and 45 character variants above were verified to deliver. I would pick the 36-character one for margin, since the limit varies with the origin and Electron version. Per-thread replacement semantics are preserved either way. A unit test asserting the composed tag stays under, say, 32 characters would guard against regressions.
This also affects the web client in Chromium browsers on Windows, since it is the same tag and platform path. macOS and Linux are not affected.
I can share the full minimal repro app and the raw logs if useful.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start in apps/web/src/components/ThreadNotificationCoordinator.tsx at line 181, where the notification tag is composed, and review the related notification path. Keep the per-thread tag within the Windows platform limit while preserving per-thread replacement semantics, then add a unit test asserting the composed tag stays short and run the relevant test suite.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- electron, typescript
- Domain
- desktop
- Issue type
- Bug
- Difficulty
- 2/5
- Estimated time
- 1-3 hours
- Activity status
- Active
- Clarity
- Clearly specified
- Newbie friendliness
- 88/100