From 92551eb13ed231d4422bce0ccca4ed853c3a8cb1 Mon Sep 17 00:00:00 2001 From: Erik Johnston Date: Fri, 3 Jul 2026 14:49:37 +0000 Subject: [PATCH] Store rejections.last_check as text, matching its column type MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit `rejections.last_check` is a TEXT column, but both writers stored `clock.time_msec()` (an int) into it, relying on the driver to coerce int→text. The native Rust driver binds typed parameters and rejects that (error serializing parameter), so marking an event rejected failed — e.g. paginating through rejected events (test_room_messages_paginate_through_rejected_events). Store the timestamp as a string, matching the declared TEXT column, rather than reintroducing loose int/text coercion in the shim. psycopg2 and sqlite are unaffected (a text value is equally valid there). Co-Authored-By: Claude Opus 4.8 (1M context) Claude-Session: https://claude.ai/code/session_01W3G4M92AmwSSZCbmtMJU3d --- synapse/storage/databases/main/events.py | 4 +++- synapse/storage/databases/main/events_worker.py | 4 +++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/synapse/storage/databases/main/events.py b/synapse/storage/databases/main/events.py index 84b38f4bf2..1aa1ad7fd9 100644 --- a/synapse/storage/databases/main/events.py +++ b/synapse/storage/databases/main/events.py @@ -3513,7 +3513,9 @@ class PersistEventsStore: values={ "event_id": event_id, "reason": reason, - "last_check": self._clock.time_msec(), + # `last_check` is a TEXT column, so store the timestamp as a + # string rather than relying on the driver to coerce an int. + "last_check": str(self._clock.time_msec()), }, ) diff --git a/synapse/storage/databases/main/events_worker.py b/synapse/storage/databases/main/events_worker.py index 65b7d251d9..c585390e7a 100644 --- a/synapse/storage/databases/main/events_worker.py +++ b/synapse/storage/databases/main/events_worker.py @@ -2702,7 +2702,9 @@ class EventsWorkerStore(SQLBaseStore): keyvalues={"event_id": event_id}, values={ "reason": rejection_reason, - "last_check": self.clock.time_msec(), + # `last_check` is a TEXT column, so store the timestamp as a + # string rather than relying on the driver to coerce an int. + "last_check": str(self.clock.time_msec()), }, ) self.db_pool.simple_update_txn(