[3.0] Stop selecting the dropped time_offset column in CreatePost_Notify - #9322
Merged
Sesquipedalian merged 2 commits intoJul 29, 2026
Conversation
The members table lost its time_offset column in 3.0, in the
DropTimeOffset migration, and User::$time_offset became a virtual
property derived from the member's time zone. User::setProperties() even
lists time_offset among the "obsolete data" it ignores.
CreatePost_Notify still asked the database for it:
mem.smiley_set, mem.time_format, mem.time_offset, mem.timezone,
so the query fails outright with "column mem.time_offset does not
exist", and the task dies on the fetch_assoc() of a false result. The
task is never marked done, so it is retried on later page loads and
takes down whichever request happens to run it:
SMF\Db\APIs\PostgreSQL::fetch_assoc(): Argument #1 ($result) must be
of type object, false given
Nobody watching a board or topic receives their notification either.
Derives the offset from mem.timezone, which the query already selects,
the same way User::$time_offset does. Also keys the parsed-message cache
by time zone rather than by offset, and drops an (int) cast that
truncated the offsets of half-hour and quarter-hour time zones.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
PHP-CS-Fixer sorts class members, and a static method does not belong in the non-static "Internal methods" group. No change to the code itself. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This was referenced Jul 29, 2026
Sesquipedalian
approved these changes
Jul 29, 2026
This was referenced Aug 2, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Note
This change was produced by an LLM. The code, the commit message and this
description were all written by Claude (Anthropic), driven by @albertlast. It has
not yet had human code review.
Everything stated below was verified by actually running it against a PostgreSQL
install of this branch, rather than only reasoned about. Even so, please review it
as untrusted work: the diagnosis may be right while the fix is not what SMF would
prefer stylistically or architecturally.
Description
CreatePost_Notifyasks the database for a column that 3.0 removed:time_offsetwas dropped from the members table by theDropTimeOffsetmigration,which converts each member's offset into a
timezonevalue first.User::$time_offsetbecame a virtual property derived from
timezone, andUser::setProperties()liststime_offsetamong the "Obsolete data. Ignore if present." keys.So the query fails outright:
and the task dies on the
fetch_assoc()of afalseresult:Two consequences. Nobody watching a board or topic ever receives their notification.
And because the task never returns success it is never removed from
background_tasks, so it is retried on subsequent requests and takes down whicheverpage happens to run it — an ordinary board index intermittently returning HTTP 500,
which is a confusing thing to chase, since the request that fails has nothing to do
with the post that queued the task.
This derives the offset from
mem.timezone, which the query already selects, thesame way
User::$time_offsetdoes. Two smaller things fall out of it:what the key is really trying to distinguish;
(int)cast is gone.Parser::$time_offsetis afloat, and the casttruncated the offsets of half-hour and quarter-hour zones, so members in, say,
Asia/KolkataorAsia/Kathmanduhad times in their notification emails shiftedby up to 45 minutes.
How this was verified
PostgreSQL 17 / PHP 8.4.23, with a member watching a board and three
CreatePost_Notifytasks sitting in the queue from earlier posts.The baseline was
release-3.0plus the pending fixes #9310–#9317, #9319 and #9320.Nothing in this change depends on those; that was simply the branch in hand.
fetch_assoc()errors logged, and all three tasks still queued afterwards,ready to break the next request too.
tasks completed and removed from the queue.
watching member gets their alert row (
content_type = 'board'), which neverappeared before.
php -lclean.Relationship to other PRs
Sources/Tasks/CreatePost_Notify.phpis not touched by any other open PR, and thefailure is independent of the login and ban work in #9310–#9319 — any post that
queues a notification triggers it.
One thing to flag: with the query fixed, the task now runs to completion for the
first time, and three warnings become visible further down that path —
Undefined array key "id_alert"atSources/Alert.php:641,:658and:659,where
$props['id_alert']is read on alert rows that have not been inserted yet.Warning-level only; the task still completes and the alert is still created. Not
addressed here, but this PR is what makes them reachable, so it seems worth saying.
Issues References (Fixes|Related|Closes)