Page MenuHomePhabricator

PHP Fatal error: Declaration of MWCallbackStream::write($string) must be compatible with Psr\Http\Message\StreamInterface::write(string $string): int in /var/www/mediawiki/includes/http/MWCallbackStream.php on line 49 with guzzlehttp/psr7 2.5.0
Closed, DuplicatePublicBUG REPORT

Description

PHP Fatal error: Declaration of MWCallbackStream::write($string) must be compatible with Psr\Http\Message\StreamInterface::write(string $string): int in /var/www/mediawiki/includes/http/MWCallbackStream.php on line 49

We use composer to install new dependencies during an image build for our MW 1.39.3 wiki

Mediawiki requires guzzlehttp/guzzle v7.4.5 for 1.39
guzzlehttp/guzzle requires guzzlehttp/psr7 ^2.4 of which the latest matching version is 2.5.0

When running v2.5.0 we get the above message on rest.php and seemingly random content pages, v2.4.4 has no issues

Event Timeline

Same here

PHP Fatal error: Declaration of MWCallbackStream::write($string) must be compatible with Psr\Http\Message\StreamInterface::write(string $string): int in /home/user/public_html/muizenmesh.co.za/wiki/includes/http/MWCallbackStream.php  on line 49

I just did a composer update --no-dev followed by a php/maintenence/update.php on our MW 1.39 wiki

Looks like this is a duplicate of T333993, which will be fixed in the next point release (1.39.4).

What is the work around for 1.39.3?

Applying the patch manually.

Looks like this is a duplicate of T333993, which will be fixed in the next point release (1.39.4).

Not really (or at least the reasoning in that task description shouldn't apply), as noted in php-fig/http-message#105 adding parameter type hints is backwards compatible.

MW 1.39.3 pins Guzzle 7.4.5, that requires guzzlehttp/psr7: ^1.9 || ^2.4, and 2.4 of that library requires psr/http-message: ^1.0 but guzzlehttp/psr7 2.5 requires psr/http-message: ^1.1 || ^2.0. psr/http-message 2.0 intrododuces return type hints, which unlike parameter type hints are not backwards compatible.

The end result is the same though: MediaWiki should have been pinning psr/http-message to ^1.0 as it was using it directly, and once the libraries it requires didn't disallow psr/http-message 2.*, it got upgraded to that version and MediaWiki broke.

I would have expected that an LTS version pins all dependencies. Wouldn't stability be here the more important goal than staying up-to-date? This case of breaking the system "out of blue air" is IMHO a warning call. Taking it seriously and changing the procedures would IMHO be an adequate response. Would the request for this stabiity with pinned versions be a new phabricator task or has this already been discussed and there is a task for it?

Pinning indirect dependencies doesn't make a lot of sense for an application which has a plugin system, as the plugins have their own dependencies and pinning might cause unnecessary conflicts Pinning is generally something better performed by the site administrator IMO (e.g. Wikimedia wikis pin versions via mediawiki-vendor).

Pinning indirect dependencies doesn't make a lot of sense for an application which has a plugin system, as the plugins have their own dependencies and pinning might cause unnecessary conflicts Pinning is generally something better performed by the site administrator IMO (e.g. Wikimedia wikis pin versions via mediawiki-vendor).

I mean, the bug here is that it is a direct dependency which wasn't pinned. I don't think a change in procedure is needed here - since it already should have been pinned as a direct dependency. It was an oversight that it wasn't. The fact that it is both a direct and indirect dependency allowed the mistake to not be noticed.

Ideally we would have some sort of test to detect this situation, but it seems like a really hard thing to automatically test for.

Ideally we would have some sort of test to detect this situation, but it seems like a really hard thing to automatically test for.

We could install direct dependencies only and then run Phan. Seems like a rare enough issue that it's not worth the effort setting up, though.

Observed the same here on my wiki. Specifically, I noticed it because I observed error 500 when searching due to autocomplete not being able to reach the needed resource, and confirmed by navigating to the rest.php page directly which would give a message similar to what Ethnopunk posted above. I went through the dependancy chain and eventually traced it back to psr/httpmessage version 2.0 being upgraded.

For me, a workaround until 1.39.4 comes out was to add this to my composer.local.json file and running composer again:

"psr/http-message": "~1"

In the case of zip downloads, how would it be? I didn't download the core with composer and although I applied the patch that Taavi recommended it doesn't work. Should I include the file "composer.local.json" then?

In the case of zip downloads, how would it be? I didn't download the core with composer and although I applied the patch that Taavi recommended it doesn't work. Should I include the file "composer.local.json" then?

This issue should not have applied to zip downloads. If you were using zip and got it it probably has a different cause. (Maybe from an extension?)

In the case of zip downloads, how would it be? I didn't download the core with composer and although I applied the patch that Taavi recommended it doesn't work. Should I include the file "composer.local.json" then?

This issue should not have applied to zip downloads. If you were using zip and got it it probably has a different cause. (Maybe from an extension?)

To clarify that statement, the files as they exist in the zip will not exhibit the issue. If you run the composer commands to update your environment, it will update the dependency files to the versions configured in the composer.json file provided in the zip. These versions have likely been updated since any given zip was released meaning that the environment no longer matches perfectly what was in the zip. Not a big deal (and actually a good idea) 99% of the time, but in this case a dependency update introduces a change that breaks MediaWiki.

Simply making the change that Taavi mentioned (or creating/updating a composer.local.json with the dependency version like I did) will not restore normal operation, you also have to run the composer update command so that composer downgrades the problem dependency according to the updates .json file(s). The output of the composer program will have a line showing that psr/http-message was downgraded from version 2.x to 1.x.

I documented what is currently happening through T336557. I followed the recommendations but it is still down the same. I don't know if it could be because I uninstalled LocalisationUpdates.

Declaration of MWCallbackStream::write($string) must be compatible with Psr\Http\Message\StreamInterface::write(string $string): int in /home/user/public_html/site/wiki/includes/http/MWCallbackStream.php on line 49

I get this when I activate semantic wiki

Like Ethnopunk I also ran into this error after installing Semantic MediaWiki (on a wiki with MediaWiki 1.39.1).

PHP Fatal error:  Declaration of MWCallbackStream::write($string) must be compatible with Psr\\Http\\Message\\StreamInterface::write(string $string): int in /var/www/michelelavazza.it/w_test/includes/http/MWCallbackStream.php on line 46

This doesn't break the wiki, but trying to access pages in the File: namespaces gives an error 500.

Observed the same here on my wiki. Specifically, I noticed it because I observed error 500 when searching due to autocomplete not being able to reach the needed resource, and confirmed by navigating to the rest.php page directly which would give a message similar to what Ethnopunk posted above. I went through the dependancy chain and eventually traced it back to psr/httpmessage version 2.0 being upgraded.

For me, a workaround until 1.39.4 comes out was to add this to my composer.local.json file and running composer again:

"psr/http-message": "~1"

Thank you, this was an extremely useful temporary fix.