Page MenuHomePhabricator

PHP Deprecated: strrpos(): Passing null to parameter #1 ($haystack) of type string is deprecated
Closed, ResolvedPublicPRODUCTION ERROR

Description

Error
normalized_message
[{reqId}] {exception_url}   PHP Deprecated: strrpos(): Passing null to parameter #1 ($haystack) of type string is deprecated
FrameLocationCall
from/srv/mediawiki/php-1.44.0-wmf.13/includes/libs/filebackend/FileBackend.php(1652)
#0[internal function]MWExceptionHandler::handleError(int, string, string, int)
#1/srv/mediawiki/php-1.44.0-wmf.13/includes/libs/filebackend/FileBackend.php(1652)strrpos(null, string)
#2/srv/mediawiki/php-1.44.0-wmf.13/includes/upload/UploadFromChunks.php(173)Wikimedia\FileBackend\FileBackend::extensionFromPath(null)
#3/srv/mediawiki/php-1.44.0-wmf.13/includes/api/ApiUpload.php(459)UploadFromChunks->concatenateChunks()
#4/srv/mediawiki/php-1.44.0-wmf.13/includes/api/ApiUpload.php(255)MediaWiki\Api\ApiUpload->getChunkResult(array)
#5/srv/mediawiki/php-1.44.0-wmf.13/includes/api/ApiUpload.php(172)MediaWiki\Api\ApiUpload->getContextResult()
#6/srv/mediawiki/php-1.44.0-wmf.13/includes/api/ApiMain.php(1973)MediaWiki\Api\ApiUpload->execute()
#7/srv/mediawiki/php-1.44.0-wmf.13/includes/api/ApiMain.php(941)MediaWiki\Api\ApiMain->executeAction()
#8/srv/mediawiki/php-1.44.0-wmf.13/includes/api/ApiMain.php(912)MediaWiki\Api\ApiMain->executeActionWithErrorHandling()
#9/srv/mediawiki/php-1.44.0-wmf.13/includes/api/ApiEntryPoint.php(152)MediaWiki\Api\ApiMain->execute()
#10/srv/mediawiki/php-1.44.0-wmf.13/includes/MediaWikiEntryPoint.php(202)MediaWiki\Api\ApiEntryPoint->execute()
#11/srv/mediawiki/php-1.44.0-wmf.13/api.php(44)MediaWiki\MediaWikiEntryPoint->run()
#12/srv/mediawiki/w/api.php(3)require(string)
#13{main}
Impact
Notes
		// Get the file extension from the last chunk
		$ext = FileBackend::extensionFromPath( $this->mVirtualTempPath );
		// Get a 0-byte temp file to perform the concatenation at
		$tmpFile = MediaWikiServices::getInstance()->getTempFSFileFactory()
			->newTempFSFile( 'chunkedupload_', $ext );

$this->mVirtualTempPath is null.

newTempFSFile wants an empty string, not null. I guess on PHP 7.4 FileBackend::extensionFromPath results in a string being returned.

Related Objects

View Standalone Graph
This task is connected to more than 200 other tasks. Only direct parents and subtasks are shown here. Use View Standalone Graph to show more of the graph.
StatusSubtypeAssignedTask
ResolvedNone
ResolvedPRODUCTION ERRORNone

Event Timeline

It would look like this in theory happens every time for the first chunk...

In this case, the file is probably small enough that it's just one chunk

Change #1114455 had a related patch set uploaded (by Jforrester; author: Jforrester):

[mediawiki/core@master] UploadFromChunks::concatenateChunks: Don't proceed if we don't have a chunk filepath to evaluate

https://gerrit.wikimedia.org/r/1114455

I'm guessing https://gerrit.wikimedia.org/r/1086000 was an attempted fix for this issue too

Reedy changed the task status from Open to In Progress.Jan 31 2025, 1:08 PM

Adding a fresh example for the convenience of working gerrit links. While not the only remaining deprecation warning on 8.1, it is by far the dominant one.

Also +1 to @Reedy's analysis in T384851#10498339 that this seems like it would happen on a single-chunk upload? (i.e., we get into concatenateChunks without ever having ended up in continueChunks, which would have initialized $this->mVirtualTempPath).

Error
normalized_message
[{reqId}] {exception_url}   PHP Deprecated: strrpos(): Passing null to parameter #1 ($haystack) of type string is deprecated
FrameLocationCall
from/srv/mediawiki/php-1.44.0-wmf.20/includes/libs/filebackend/FileBackend.php(1652)
#0[internal function]MWExceptionHandler::handleError(int, string, string, int)
#1/srv/mediawiki/php-1.44.0-wmf.20/includes/libs/filebackend/FileBackend.php(1652)strrpos(null, string)
#2/srv/mediawiki/php-1.44.0-wmf.20/includes/upload/UploadFromChunks.php(173)Wikimedia\FileBackend\FileBackend::extensionFromPath(null)
#3/srv/mediawiki/php-1.44.0-wmf.20/includes/api/ApiUpload.php(459)UploadFromChunks->concatenateChunks()
#4/srv/mediawiki/php-1.44.0-wmf.20/includes/api/ApiUpload.php(255)MediaWiki\Api\ApiUpload->getChunkResult(array)
#5/srv/mediawiki/php-1.44.0-wmf.20/includes/api/ApiUpload.php(172)MediaWiki\Api\ApiUpload->getContextResult()
#6/srv/mediawiki/php-1.44.0-wmf.20/includes/api/ApiMain.php(2005)MediaWiki\Api\ApiUpload->execute()
#7/srv/mediawiki/php-1.44.0-wmf.20/includes/api/ApiMain.php(947)MediaWiki\Api\ApiMain->executeAction()
#8/srv/mediawiki/php-1.44.0-wmf.20/includes/api/ApiMain.php(918)MediaWiki\Api\ApiMain->executeActionWithErrorHandling()
#9/srv/mediawiki/php-1.44.0-wmf.20/includes/api/ApiEntryPoint.php(152)MediaWiki\Api\ApiMain->execute()
#10/srv/mediawiki/php-1.44.0-wmf.20/includes/MediaWikiEntryPoint.php(202)MediaWiki\Api\ApiEntryPoint->execute()
#11/srv/mediawiki/php-1.44.0-wmf.20/api.php(44)MediaWiki\MediaWikiEntryPoint->run()
#12/srv/mediawiki/w/api.php(3)require(string)
#13{main}

Also +1 to @Reedy's analysis in T384851#10498339 that this seems like it would happen on a single-chunk upload? (i.e., we get into concatenateChunks without ever having ended up in continueChunks, which would have initialized $this->mVirtualTempPath).

I have to wonder if bailing out with an error as in the proposed patch will in theory make things worse, breaking uploads that otherwise work (even if creating logspam invisible to users)...

I have to wonder if bailing out with an error as in the proposed patch will in theory make things worse, breaking uploads that otherwise work (even if creating logspam invisible to users)...

Agreed, yeah - from a quick look at the logs from one recent example request, it seems like these indeed work? https://logstash.wikimedia.org/goto/aa261c6db84c14f1c846f2d024c368b9

That example also seems to corroborate the single-chunk theory.

Of course, it might be that there's something subtle I'm missing about the motivation for carrying over the extension to the TempFSFile name ... In any case, it seems like it works with extensionFromPath having returned empty string, as it has previously under 7.4 (just silently).

Reedy triaged this task as High priority.Mar 13 2025, 10:28 PM

I'm guessing https://gerrit.wikimedia.org/r/1086000 was an attempted fix for this issue too

^ I wonder if that is potentially a reasonable fix...

Change #1086000 had a related patch set uploaded (by Reedy; author: Paladox):

[mediawiki/core@master] FileBackend: PHP Deprecated: strrpos(): Passing null to parameter #1 ($haystack)

https://gerrit.wikimedia.org/r/1086000

Agreed that https://gerrit.wikimedia.org/r/1086000 is probably a reasonable fix for the deprecation warning, as it maintains the existing behavior if $path is indeed null (returns empty string).

Other options that come to mind:

If it does somehow matter that the TempFSFile into which we concatenate has the same extension as $this->mVirtualTempPath, then we could presumably special-case $chunkIndex === 0 in concatenateChunks to initialize it - e.g., insert the "missing" call to $this->getChunkStatus(). Alternatively, I guess we could avoid the DB query by using $this->mStashFile->getPath() in this first-and-only-chunk case, which I think ends up with the same extension (i.e., as the us_path column in uploadstash).

If it doesn't matter, and I have a hard time imagining how it could given that single-chunk uploads have $ext empty and that seems to be fine (it's just that we're only now learning this is the case thanks to deprecation warnings), maybe we can skip the dependency on $this->mVirtualTempPath entirely?

I'm on train duty this week and wanted to note that this error has been persistent for a couple of months and is currently the second most frequent in logspam-watch output.

Change #1086000 merged by jenkins-bot:

[mediawiki/core@master] FileBackend: PHP Deprecated: strrpos(): Passing null to parameter #1 ($haystack)

https://gerrit.wikimedia.org/r/1086000

Change #1132734 had a related patch set uploaded (by Reedy; author: Paladox):

[mediawiki/core@REL1_43] FileBackend: PHP Deprecated: strrpos(): Passing null to parameter #1 ($haystack)

https://gerrit.wikimedia.org/r/1132734

Change #1132735 had a related patch set uploaded (by Reedy; author: Paladox):

[mediawiki/core@REL1_42] FileBackend: PHP Deprecated: strrpos(): Passing null to parameter #1 ($haystack)

https://gerrit.wikimedia.org/r/1132735

Change #1132736 had a related patch set uploaded (by Reedy; author: Paladox):

[mediawiki/core@REL1_39] FileBackend: PHP Deprecated: strrpos(): Passing null to parameter #1 ($haystack)

https://gerrit.wikimedia.org/r/1132736

Change #1132737 had a related patch set uploaded (by Reedy; author: Paladox):

[mediawiki/core@wmf/1.44.0-wmf.22] FileBackend: PHP Deprecated: strrpos(): Passing null to parameter #1 ($haystack)

https://gerrit.wikimedia.org/r/1132737

Change #1132736 merged by jenkins-bot:

[mediawiki/core@REL1_39] FileBackend: PHP Deprecated: strrpos(): Passing null to parameter #1 ($haystack)

https://gerrit.wikimedia.org/r/1132736

Change #1132735 merged by jenkins-bot:

[mediawiki/core@REL1_42] FileBackend: PHP Deprecated: strrpos(): Passing null to parameter #1 ($haystack)

https://gerrit.wikimedia.org/r/1132735

Change #1132734 merged by jenkins-bot:

[mediawiki/core@REL1_43] FileBackend: PHP Deprecated: strrpos(): Passing null to parameter #1 ($haystack)

https://gerrit.wikimedia.org/r/1132734

Change #1132737 merged by jenkins-bot:

[mediawiki/core@wmf/1.44.0-wmf.22] FileBackend: PHP Deprecated: strrpos(): Passing null to parameter #1 ($haystack)

https://gerrit.wikimedia.org/r/1132737

Mentioned in SAL (#wikimedia-operations) [2025-03-31T22:13:48Z] <reedy@deploy1003> Synchronized php-1.44.0-wmf.22/includes/libs/filebackend/FileBackend.php: T384851 (duration: 02m 14s)

Reedy lowered the priority of this task from High to Medium.Mar 31 2025, 10:14 PM

Last log entry was on Mar 31, 2025 @ 21:50:35.374, so I think this worked. Shall we call this Resolved?

Change #1134760 had a related patch set uploaded (by Umherirrender; author: Umherirrender):

[mediawiki/core@master] upload: Set UploadFromChunks::mVirtualTempPath on first chunk

https://gerrit.wikimedia.org/r/1134760

Change #1134760 merged by jenkins-bot:

[mediawiki/core@master] upload: Set UploadFromChunks::mVirtualTempPath on first chunk

https://gerrit.wikimedia.org/r/1134760

Change #1114455 abandoned by Umherirrender:

[mediawiki/core@master] UploadFromChunks::concatenateChunks: Don't proceed if we don't have a chunk filepath to evaluate

Reason:

Fixed via I27516ce6ce10793a748475338a2810537f4cb223

https://gerrit.wikimedia.org/r/1114455

Umherirrender removed a project: Patch-For-Review.
Umherirrender subscribed.

No further backport needed, as 1a4d7d410c527f6a9f57b5c3e6f733a4a64f41c1 is enough to avoid the deprecation warning, without breaking the action.