Page MenuHomePhabricator

HTML-formatted deprecation warnings included in API responses which should be pure JSON
Open, Needs TriagePublicBUG REPORT

Description

Steps to replicate the issue (include links if applicable):

  • Deploy a mediawiki instance such that operations result in deprecation warnings about the PHP Requests library
  • Send an API request which should return pure JSON

What happens?:

You get a response which is mixed HTML and JSON - it starts with HTML-formatted deprecation warnings, then the actual JSON response follows. Most clients will choke on this as they are expecting the response to be pure JSON and just feed it to a JSON parser, which will error out on the HTML.

What should have happened instead?:

You should get a pure JSON response, either with the deprecation warnings omitted (nobody is likely to see them in this workflow anyway) or somehow translated to JSON.

Software version (skip for WMF-hosted wikis like Wikipedia):

We (Fedora) hit this with mediawiki 1.39.3, PHP 8.2.5 and an old version of the Requests library (1.8.0). Updating Requests to 2.0.6 may well avoid the problem (we're working on this), but it still seems like generally wrong behaviour: the API shouldn't pollute JSON response with HTML-formatted deprecation notices in general.

More details

This is an example request (the 'data' portion of the request, via a Python client library - mwclient):

OrderedDict([('meta', 'userinfo|userinfo'), ('uiprop', 'groups|rights|blockinfo|hasmsg'), ('continue', ''), ('action', 'query'), ('format', 'json')])

and the response:

<br />
<b>Deprecated</b>:  Return type of Requests_Cookie_Jar::offsetExists($key) should either be compatible with ArrayAccess::offsetExists(mixed $offset): bool, or the #[\ReturnTypeWillChange] attribute should be used to temporarily suppress the notice in <b>/usr/share/php/rmccue/Requests/Requests/Cookie/Jar.php</b> on line <b>63</b><br />
<br />
<b>Deprecated</b>:  Return type of Requests_Cookie_Jar::offsetGet($key) should either be compatible with ArrayAccess::offsetGet(mixed $offset): mixed, or the #[\ReturnTypeWillChange] attribute should be used to temporarily suppress the notice in <b>/usr/share/php/rmccue/Requests/Requests/Cookie/Jar.php</b> on line <b>73</b><br />
<br />
<b>Deprecated</b>:  Return type of Requests_Cookie_Jar::offsetSet($key, $value) should either be compatible with ArrayAccess::offsetSet(mixed $offset, mixed $value): void, or the #[\ReturnTypeWillChange] attribute should be used to temporarily suppress the notice in <b>/usr/share/php/rmccue/Requests/Requests/Cookie/Jar.php</b> on line <b>89</b><br />
<br />
<b>Deprecated</b>:  Return type of Requests_Cookie_Jar::offsetUnset($key) should either be compatible with ArrayAccess::offsetUnset(mixed $offset): void, or the #[\ReturnTypeWillChange] attribute should be used to temporarily suppress the notice in <b>/usr/share/php/rmccue/Requests/Requests/Cookie/Jar.php</b> on line <b>102</b><br />
<br />
<b>Deprecated</b>:  Return type of Requests_Cookie_Jar::getIterator() should either be compatible with IteratorAggregate::getIterator(): Traversable, or the #[\ReturnTypeWillChange] attribute should be used to temporarily suppress the notice in <b>/usr/share/php/rmccue/Requests/Requests/Cookie/Jar.php</b> on line <b>111</b><br />
<br />
<b>Deprecated</b>:  http_build_query(): Passing null to parameter #2 ($numeric_prefix) of type string is deprecated in <b>/usr/share/php/rmccue/Requests/Requests/Transport/cURL.php</b> on line <b>345</b><br />
<br />
<b>Deprecated</b>:  Return type of Requests_Utility_CaseInsensitiveDictionary::offsetExists($key) should either be compatible with ArrayAccess::offsetExists(mixed $offset): bool, or the #[\ReturnTypeWillChange] attribute should be used to temporarily suppress the notice in <b>/usr/share/php/rmccue/Requests/Requests/Utility/CaseInsensitiveDictionary.php</b> on line <b>40</b><br />
<br />
<b>Deprecated</b>:  Return type of Requests_Utility_CaseInsensitiveDictionary::offsetGet($key) should either be compatible with ArrayAccess::offsetGet(mixed $offset): mixed, or the #[\ReturnTypeWillChange] attribute should be used to temporarily suppress the notice in <b>/usr/share/php/rmccue/Requests/Requests/Utility/CaseInsensitiveDictionary.php</b> on line <b>51</b><br />
<br />
<b>Deprecated</b>:  Return type of Requests_Utility_CaseInsensitiveDictionary::offsetSet($key, $value) should either be compatible with ArrayAccess::offsetSet(mixed $offset, mixed $value): void, or the #[\ReturnTypeWillChange] attribute should be used to temporarily suppress the notice in <b>/usr/share/php/rmccue/Requests/Requests/Utility/CaseInsensitiveDictionary.php</b> on line <b>68</b><br />
<br />
<b>Deprecated</b>:  Return type of Requests_Utility_CaseInsensitiveDictionary::offsetUnset($key) should either be compatible with ArrayAccess::offsetUnset(mixed $offset): void, or the #[\ReturnTypeWillChange] attribute should be used to temporarily suppress the notice in <b>/usr/share/php/rmccue/Requests/Requests/Utility/CaseInsensitiveDictionary.php</b> on line <b>82</b><br />
<br />
<b>Deprecated</b>:  Return type of Requests_Utility_CaseInsensitiveDictionary::getIterator() should either be compatible with IteratorAggregate::getIterator(): Traversable, or the #[\ReturnTypeWillChange] attribute should be used to temporarily suppress the notice in <b>/usr/share/php/rmccue/Requests/Requests/Utility/CaseInsensitiveDictionary.php</b> on line <b>91</b><br />
{"batchcomplete":"","query":{"userinfo":{"id":15360,"name":"Coconut","groups":["*","user","autoconfirmed"],"rights":["read","edit","createpage","createtalk","writeapi","viewmywatchlist","editmywatchlist","viewmyprivateinfo","editmyprivateinfo","editmyoptions","autocreateaccount","move","move-subpages","move-rootuserpages","move-categorypages","movefile","upload","reupload","reupload-shared","minoredit","editmyusercss","editmyuserjson","editmyuserjs","editmyuserjsredirect","purge","sendemail","applychangetags","changetags","editcontentmodel","skipcaptcha","autoconfirmed","editsemiprotected"]}}}

note the actual JSON response is down there at the bottom (starting {"batchcomplete" , but it's preceded by a bunch of HTML-formatted junk.

Event Timeline

Just in case anyone else runs across the same deprecation messages and winds up here looking for help: yeah, upgrading Requests to 2.0.6 avoids the problem (once we lined up all the relevant ducks to make that port work properly).