Repository navigation
[3.0] Read cached member data back the way it was written - #9628
Merged
Sesquipedalian merged 1 commit intoSep 5, 2026
Merged
Conversation
Two faults in the same block of User::loadUserData(), one hiding the other.
The branch for the current user reads
if (($data = CacheApi::get('user_settings-' . $id, 60) == null))
which closes the assignment around the comparison, so $data is handed a bool
rather than the cached profile and the is_array() guard below throws it away.
The user_settings cache has therefore never been read since this was rewritten
as a class; 2.1 has the parentheses in the right place. Nothing looked wrong,
because a cache that is never read is only a cache that never helps.
With that corrected, the line below it starts fatalling for everyone rather
than only for other members at cache level 3:
SMF\UserDataset::tryFrom(): Argument #1 ($value) must be of type string,
SMF\UserDataset given
What goes into the cache is self::$profiles[$id], whose dataset entry is the
enum itself, so tryFrom() is being handed back exactly what was stored. At
level 3 this took out the board index, any board and any topic on the second
request, the first having populated the cache the second one read.
An entry that has no dataset at all still needs the fallback, so the
conversion stays for that case and is skipped when there is already an enum.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Signed-off-by: albertlast <mathiaspapealbert@hotmail.com>
Sesquipedalian
approved these changes
Sep 5, 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.
Description
Two faults in the same block of
User::loadUserData(), one hiding the other.The branch for the current user reads
which closes the assignment around the comparison, so
$datais handed a bool rather than the cached profile, and theis_array()guard below throws it away. Theuser_settingscache has therefore never been read since this was rewritten as a class. 2.1 has the parentheses in the right place:Nothing looked wrong, because a cache that is never read is only a cache that never helps.
With that corrected, the line below it starts throwing for everyone rather than only for other members at cache level 3:
What goes into the cache is
self::$profiles[$id], whosedatasetentry is the enum itself — the line a few lines above calls->includes()on it — sotryFrom()is being handed back exactly what was stored. At cache level 3 this took out the board index, any board and any topic on the second request, the first having filled the cache that the second one read. It surfaces as a 500 withUndefined array key "categories"behind it inBoardIndex.template.php.An entry that has no dataset at all still needs the fallback, so the conversion stays for that case and is skipped when there is already an enum.
How this was checked
By hand against a running forum: at
$cache_enable = 3, the board index returns 200 on the first request and 500 on every one after it, andsmf_log_errorsrecords thetryFrom()TypeError withloadUserDatain the backtrace. After the fix, repeated requests to the board index, a board and a topic all return 200 and render byte-identical to the same pages with caching switched off.Notes for review
No regression test.
User::loadUserData()needsDb::$db, and the unit suite has no database connection, so this is not reachable from it. Per AGENTS.md I am saying so rather than contorting the code or faking a connection to force it under test.Sources/User.phpis touched by several open PRs, including #9302 and the external authentication series. None of them touches this block — I checked every open PR that changes the file foruser_settings-,member_data-orUserDataset::tryFromand none has a hit.Issues References (Fixes|Related|Closes)
🤖 Generated with Claude Code