From 9617087c167a8290806f7acbfa7eb3951dc34d62 Mon Sep 17 00:00:00 2001 From: "exe.dev user" Date: Thu, 16 Apr 2026 14:57:49 +0000 Subject: [PATCH] fix(v2): compare process_after as datetime, not raw string Scheduled tasks stored process_after as ISO-8601 with `T` and `Z` (e.g. `2026-04-16T14:37:00Z`) but the due-check queries compared it via raw `<=` against `datetime('now')`, which returns space-separated format (`2026-04-16 14:37:00`). Since `'T' (0x54) > ' ' (0x20)`, every ISO-formatted process_after sorted greater than any SQLite-format `now`, so tasks were never picked up by either the host sweep's countDueMessages or the container's getPendingMessages. Wrapping process_after in datetime() normalises both sides before comparison. Recurrence rows (written by retryWithBackoff using datetime('now', ...)) already had SQLite format and were unaffected, which is why the bug only surfaced for agent-scheduled tasks. Co-Authored-By: Claude Opus 4.6 (1M context) --- container/agent-runner/src/db/messages-in.ts | 2 +- src/db/session-db.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/container/agent-runner/src/db/messages-in.ts b/container/agent-runner/src/db/messages-in.ts index b3e713d..8192350 100644 --- a/container/agent-runner/src/db/messages-in.ts +++ b/container/agent-runner/src/db/messages-in.ts @@ -37,7 +37,7 @@ export function getPendingMessages(): MessageInRow[] { .prepare( `SELECT * FROM messages_in WHERE status = 'pending' - AND (process_after IS NULL OR process_after <= datetime('now')) + AND (process_after IS NULL OR datetime(process_after) <= datetime('now')) ORDER BY timestamp ASC`, ) .all() as MessageInRow[]; diff --git a/src/db/session-db.ts b/src/db/session-db.ts index 32cd8f4..8327123 100644 --- a/src/db/session-db.ts +++ b/src/db/session-db.ts @@ -145,7 +145,7 @@ export function countDueMessages(db: Database.Database): number { .prepare( `SELECT COUNT(*) as count FROM messages_in WHERE status = 'pending' - AND (process_after IS NULL OR process_after <= datetime('now'))`, + AND (process_after IS NULL OR datetime(process_after) <= datetime('now'))`, ) .get() as { count: number } ).count;