Repository navigation
[Bug]: A thread that woke from snooze cannot be snoozed again to the same wake time #14298
Description
Activity
- changed the title
[-][Bug]: Snoozing a woken thread again with the same option is accepted but does nothing[/-][+][Bug]: A thread that woke from snooze cannot be snoozed again to the same wake time[/+]on Sep 29, 2026 PR opened: #14299. It removes the same-wake-time branch in the decider and its optimistic twin, so every snooze stamps a fresh
snoozedAt. The existing duplicate-snooze test now asserts the fix and fails without it.Triage
Confirmed on
mainatd2c9281b81. A re-snooze to the same wake time keeps the originalsnoozedAt, so a failure or completion that is still newer than that stamp keeps the thread in the inbox.thread.snoozeinapps/server/src/orchestration/decider.tstreats an unchangedsnoozedUntilas a duplicate and re-emits the storedsnoozedAtandupdatedAt. The optimistic twin inpackages/client-runtime/src/state/threadCommands.tsdoes the same (snoozedAt: thread.snoozedUntil === input.snoozedUntil ? (thread.snoozedAt ?? now) : now). The projector copiespayload.snoozedAtthrough, so the row never moves. The reported events match that: six acceptedthread.snoozedevents, all still stamped17:30:47.626.Raising a hand does not clear the snooze fields.
threadRaisedHandWhileSnoozedonly stops the thread from classifying as snoozed when a session error'supdatedAt, or a completed turn'scompletedAt, is newer thansnoozedAt.snoozedUntilstays set, so the next click of the same preset compares equal and the old stamp wins. The comment next to that check already says a snooze of an already-failed thread means "I saw it, not now". This branch makes that false whenever the wake time does not change.Calendar presets are stable.
resolveSnoozePresetspins This evening, Tomorrow, and Next week to a local clock time, so repeating Next week is the samesnoozedUntil(here2026-10-05T07:00Z). In 1 hour and In 3 hours mint a new instant on every click, which is why a different option hides the thread.This is not a duplicate of #6368. That issue's first half, completed work waking a snoozed thread, is the current raised-hand policy and is untouched here. Its "re-snooze may not land in Snoozed" half is this bug, but #6368 has no cause and also asks for the wake policy to change. Closed #7179 only removed the completion comparison in
threadRaisedHandWhileSnoozedand never merged; it did not touch this branch. #10545 is why a usage-limit stop reads as Failed. That is what raised the hand, not why the re-snooze was ignored.The same-wake branch is not the retry guard.
OrchestrationEnginereturns the existing receipt before the decider runs, so a replayedcommandIdnever reaches this code. A double-click is a new command and only moves the stamp by milliseconds. The raised-hand checks are strict>, so that is enough.Always stamp
snoozedAtandupdatedAtfrom now, in the decider and the optimistic twin. The decider test "re-emits idempotently for a duplicate snooze to the same wake time" asserts the bug and has to flip. Open PR #14299 does that.Workaround until it ships: pick a different wake time.
- addedbugSomething is broken or behaving incorrectly.Something is broken or behaving incorrectly.via-triageFiled through npx t3 triageFiled through npx t3 triage
on Sep 29, 2026 Still happens on V2:
thread.snoozeinOrchestrator.tskeeps the originalsnoozedAtfor a re-snooze to the same wake time. Fix rebuilt on V2 main in #15881.- added a commit that references this issue
on Oct 6, 2026
Before submitting
Area
apps/server
Steps to reproduce
Expected behavior
The thread leaves the inbox until the new wake time.
Actual behavior
The command is accepted, but the thread stays in the inbox as Failed. Snoozing again with the same option does the same every time. I did it six times in 12 minutes on one thread. It looks like the snooze hangs or does nothing, with no toast.
Cause
A re-snooze to the same wake time is treated as a duplicate, and the original
snoozedAtis kept:apps/server/src/orchestration/decider.ts,thread.snooze, theexistingSnoozedAtbranchpackages/client-runtime/src/state/threadCommands.ts,snoozedAt: thread.snoozedUntil === input.snoozedUntil ? (thread.snoozedAt ?? now) : nowThe raised-hand check in
threadRaisedHandWhileSnoozed(packages/client-runtime/src/state/threadSettled.ts) comparessession.updatedAtandlatestTurn.completedAtagainst that stalesnoozedAt. The failure is still newer, so the thread never classifies as snoozed again until the user picks a different wake time. Presets such as Tomorrow and Next week resolve to fixed clock times, so repeating the same option is the normal case.Suggested fix
Remove the same-wake-time branch in both places, so an explicit snooze always stamps
snoozedAtnow. Re-snoozing means "I saw it, not now", so it should reset the raised-hand baseline. Real retries are already deduplicated bycommandIdreceipts, and a double-click only moves the stamp by milliseconds. This is a net deletion. Update the existingdecider.snoozed.test.tscase ("re-emits idempotently for a duplicate snooze to the same wake time") to assert a freshsnoozedAt. I can open the PR.Impact
Minor bug or occasional failure
Version or commit
t3@0.0.43-nightly.20260929.2428 (main d2c9281). The code is unchanged on current main.
Environment
Linux host running
t3 serveas a service, macOS desktop client connected remotely, Claude provider. Not specific to remote connections: the server accepted every command.Logs or stack traces
A second thread shows the same pattern (snoozed 17:30:40, error at 18:05:45, re-snoozes at 18:08 and 18:10 all keep 17:30:40).
Screenshots, recordings, or supporting files
Both threads after six "Next week" re-snoozes between 17:58 and 18:10. Every command was accepted, and both rows are still in the inbox as Failed:
Workaround
Snooze with a different option, such as Tomorrow or 3 hours. That stamps a fresh
snoozedAtand the snooze holds.Related