Steps to reproduce:
- Run the populateCheckUserTable.php maintenance script
- Load results for a user who had entries in the recentchanges table before populating the checkuser table
- Switch to the "Timeline" tab
What happens:
A PHP error shows:
[656883fe86f50c5bfc74bb4c] /w/index.php?title=Special:Investigate/Timeline&token=eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJleHAiOjE2NTczNTc4OTIsImRhdGEiOiJrOExjQU8xZVlnYVE3OGc5VU4rb1E1WGNBalpTRVM3dVlRcjBld2VINjI0a2tod29oSmFTenNuV2VRPT0ifQ.4rZ7lNv5D9To74P0U59DYEVrfYha5Io508b9q-zeOJ4 TypeError: Argument 1 passed to MediaWiki\CheckUser\TimelineRowFormatter::getUserAgent() must be of the type string, null given, called in /var/www/html/w/extensions/CheckUser/src/TimelineRowFormatter.php on line 101 Backtrace: from /var/www/html/w/extensions/CheckUser/src/TimelineRowFormatter.php(175) #0 /var/www/html/w/extensions/CheckUser/src/TimelineRowFormatter.php(101): MediaWiki\CheckUser\TimelineRowFormatter->getUserAgent(NULL) #1 /var/www/html/w/extensions/CheckUser/src/TimelinePager.php(118): MediaWiki\CheckUser\TimelineRowFormatter->getFormattedRowItems(stdClass) #2 /var/www/html/w/includes/pager/ReverseChronologicalPager.php(115): MediaWiki\CheckUser\TimelinePager->formatRow(stdClass) #3 /var/www/html/w/includes/pager/IndexPager.php(634): ReverseChronologicalPager->getRow(stdClass) #4 /var/www/html/w/extensions/CheckUser/src/TimelinePager.php(180): IndexPager->getBody() #5 /var/www/html/w/extensions/CheckUser/src/Specials/SpecialInvestigate.php(405): MediaWiki\CheckUser\TimelinePager->getFullOutput() #6 /var/www/html/w/extensions/CheckUser/src/Specials/SpecialInvestigate.php(189): MediaWiki\CheckUser\Specials\SpecialInvestigate->addTabContent(string) #7 /var/www/html/w/includes/specialpage/SpecialPage.php(691): MediaWiki\CheckUser\Specials\SpecialInvestigate->execute(string) #8 /var/www/html/w/includes/specialpage/SpecialPageFactory.php(1421): SpecialPage->run(string) #9 /var/www/html/w/includes/MediaWiki.php(316): MediaWiki\SpecialPage\SpecialPageFactory->executePath(string, RequestContext) #10 /var/www/html/w/includes/MediaWiki.php(913): MediaWiki->performRequest() #11 /var/www/html/w/includes/MediaWiki.php(569): MediaWiki->main() #12 /var/www/html/w/index.php(50): MediaWiki->run() #13 /var/www/html/w/index.php(46): wfIndexMain() #14 {main}
What should happen:
The Timeline tab should show without an error
Extra info
This is likely because the TimelineRowFormatter does not expect that there may be a null in the DB for the user agent. This is then passed to getUserAgent which has the argument type as a string. Either the DB needs to be changed so that only strings can be stored (and in the case of no user agent due to conversion from recentchanges an empty string is stored) or this needs to handle a nullable string.
Ideally TimelineRowFormatter should be inspected to see where similar issues could occur due to the DB potentially allowing null but TimelineRowFormatter expecting a non-nullable.