Page MenuHomePhabricator

Error: Object of class Wikimedia\Message\ScalarParam could not be converted to string (in action=visualeditor)
Closed, ResolvedPublicBUG REPORT

Description

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

What happens?:

[2023-11-27T01:32:12.763653+00:00] exception.ERROR: [61e20229e7d901aeed0e5f49] /w/api.php?action=visualeditor&format=json&paction=parse&page=MediaWiki%3AConfig-invalid-db-prefix%2Fen&uselang=en&formatversion=2&oldid=2317133   Error: Object of class Wikimedia\Message\ScalarParam could not be converted to string {"exception":"[object] (Error(code: 0): Object of class Wikimedia\\Message\\ScalarParam could not be converted to string at /srv/mediawiki/tags/2023-11-23_14:14:09/includes/language/Message.php:1330)
[stacktrace]
#0 /srv/mediawiki/tags/2023-11-23_14:14:09/includes/language/Message.php(1330): strtr()
#1 /srv/mediawiki/tags/2023-11-23_14:14:09/includes/language/Message.php(1002): Message->replaceParameters()
#2 /srv/mediawiki/tags/2023-11-23_14:14:09/includes/language/Message.php(1059): Message->format()
#3 /srv/mediawiki/tags/2023-11-23_14:14:09/includes/api/ApiUsageException.php(58): Message->text()
#4 /srv/mediawiki/tags/2023-11-23_14:14:09/includes/api/ApiUsageException.php(74): ApiUsageException->__construct()
#5 /srv/mediawiki/tags/2023-11-23_14:14:09/includes/api/ApiBase.php(1530): ApiUsageException::newWithMessage()
#6 /srv/mediawiki/tags/2023-11-23_14:14:09/extensions/VisualEditor/includes/ApiParsoidTrait.php(91): ApiBase->dieWithError()
#7 /srv/mediawiki/tags/2023-11-23_14:14:09/extensions/VisualEditor/includes/ApiParsoidTrait.php(112): MediaWiki\\Extension\\VisualEditor\\ApiVisualEditor->dieWithRestHttpException()
#8 /srv/mediawiki/tags/2023-11-23_14:14:09/extensions/VisualEditor/includes/ApiVisualEditor.php(232): MediaWiki\\Extension\\VisualEditor\\ApiVisualEditor->requestRestbasePageHtml()
#9 /srv/mediawiki/tags/2023-11-23_14:14:09/includes/api/ApiMain.php(1931): MediaWiki\\Extension\\VisualEditor\\ApiVisualEditor->execute()
#10 /srv/mediawiki/tags/2023-11-23_14:14:09/includes/api/ApiMain.php(908): ApiMain->executeAction()
#11 /srv/mediawiki/tags/2023-11-23_14:14:09/includes/api/ApiMain.php(879): ApiMain->executeActionWithErrorHandling()
#12 /srv/mediawiki/tags/2023-11-23_14:14:09/api.php(95): ApiMain->execute()
#13 /srv/mediawiki/tags/2023-11-23_14:14:09/api.php(48): wfApiMain()
#14 {main}
","exception_url":"/w/api.php?action=visualeditor&format=json&paction=parse&page=MediaWiki%3AConfig-invalid-db-prefix%2Fen&uselang=en&formatversion=2&oldid=2317133","reqId":"61e20229e7d901aeed0e5f49","caught_by":"entrypoint"} []

Var_dump gives:

["key":protected]=>
string(21) "rest-permission-error"
["keysToTry":protected]=>
array(1) {
  [0]=>
  string(21) "rest-permission-error"
}
["parameters":protected]=>
array(1) {
  [0]=>
  object(Wikimedia\Message\ScalarParam)#846 (2) {
    ["type":protected]=>
    string(4) "text"
    ["value":protected]=>
    string(13) "stashbasehtml"
  }
}

Possibly caused by rMW32c12be6fe33: Re-apply "Rest: replace use of deprecated pingLimiter method". Potential train blocker?

What should have happened instead?:

No uncaught exception

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

About one week old master branch.

Event Timeline

The problem seems to be something about how the ApiParsoidTrait dieWithRestHttpException is trying to pass the exception error message from the LocalizedHttpException through to the API.

$this->dieWithError( [
	'message' => $msg->getKey() ?? '',
	'params' => $msg->getParams() ?? []
] );

With the output of $msg->getParams() here apparently producing things that you can't pass to a plain Message as its parameters. It seems a little bit wrong that passing a MessageParam into a Message constructor wouldn't wind up with a usable message, but Message is pretty vague about acceptable types (and, naming aside, doesn't actually seem to know about or use MessageParam -- it certainly doesn't call any of its methods 🤷🏻).

I'm not entirely sure how this all ties together, but it looks like it might be valid to change what ApiParsoidTrait is doing to (approximately) $this->dieWithError( $msg ) which would avoid it trying to recreate the whole message object, and might thus avert the issue. Or, if it doesn't, it pushes the issue upstream, because $msg would already be unusable when we get it.

The underlying problem is that the REST framework uses MessageValue is was intended as a nicer replacement of Message. MessageParam works with MessageValue, but not with Message. The two should be made to work together more nicely...

Hm, yeah, my suggestion wouldn't work at all, because ApiMessage::create can't take a MessageValue.

So, simplest approach right now: enhance ApiMessage::create to cope with MessageValues, since it's serving as the interface between these systems already? Or at least make it notice when it's being given something like that and die with a nicely generic error, rather than something unhandled. A super quick search doesn't turn up any convenient helpers for converting between these systems, but the simple case looks pretty easy (just map the MessageValue parameters via getValue, maybe abandoning it all if we encounter a ListParam).

It seems that it sort of coincidentally worked before the pingLimiter change because we never got any messages with parameters here before, and MessageValue still keeps the message key as a string.

One I spotted this morning:

Error
labels.normalized_message
[{reqId}] {exception_url}   Error: Object of class Wikimedia\Message\ScalarParam could not be converted to string
error.stack_trace
from /srv/mediawiki/php-1.42.0-wmf.7/includes/language/Message.php(1330)
#0 /srv/mediawiki/php-1.42.0-wmf.7/includes/language/Message.php(1330): strtr(string, array)
#1 /srv/mediawiki/php-1.42.0-wmf.7/includes/language/Message.php(1002): Message->replaceParameters(string, string, string)
#2 /srv/mediawiki/php-1.42.0-wmf.7/includes/language/Message.php(1059): Message->format(string)
#3 /srv/mediawiki/php-1.42.0-wmf.7/includes/api/ApiUsageException.php(58): Message->text()
#4 /srv/mediawiki/php-1.42.0-wmf.7/includes/api/ApiUsageException.php(74): ApiUsageException->__construct(MediaWiki\Extension\VisualEditor\ApiVisualEditor, StatusValue, integer, NULL)
#5 /srv/mediawiki/php-1.42.0-wmf.7/includes/api/ApiBase.php(1530): ApiUsageException::newWithMessage(MediaWiki\Extension\VisualEditor\ApiVisualEditor, array, NULL, NULL, integer)
#6 /srv/mediawiki/php-1.42.0-wmf.7/extensions/VisualEditor/includes/ApiParsoidTrait.php(91): ApiBase->dieWithError(array)
#7 /srv/mediawiki/php-1.42.0-wmf.7/extensions/VisualEditor/includes/ApiParsoidTrait.php(112): MediaWiki\Extension\VisualEditor\ApiVisualEditor->dieWithRestHttpException(MediaWiki\Rest\LocalizedHttpException)
#8 /srv/mediawiki/php-1.42.0-wmf.7/extensions/VisualEditor/includes/ApiVisualEditor.php(232): MediaWiki\Extension\VisualEditor\ApiVisualEditor->requestRestbasePageHtml(MediaWiki\Revision\RevisionStoreRecord)
#9 /srv/mediawiki/php-1.42.0-wmf.7/includes/api/ApiMain.php(1931): MediaWiki\Extension\VisualEditor\ApiVisualEditor->execute()
#10 /srv/mediawiki/php-1.42.0-wmf.7/includes/api/ApiMain.php(908): ApiMain->executeAction()
#11 /srv/mediawiki/php-1.42.0-wmf.7/includes/api/ApiMain.php(879): ApiMain->executeActionWithErrorHandling()
#12 /srv/mediawiki/php-1.42.0-wmf.7/api.php(95): ApiMain->execute()
#13 /srv/mediawiki/php-1.42.0-wmf.7/api.php(48): wfApiMain()
#14 /srv/mediawiki/w/api.php(3): require(string)
#15 {main}

Frequency of this seems to have increased somewhat, possibly with rollout of 1.42.0-wmf.9 (T350085) to group1.

2023-12-14-09:10:36.png (245×622 px, 15 KB)

I'm on train duty this week and I notice that this error message is the most frequent of all so far.

Change 983942 had a related patch set uploaded (by Bartosz Dziewoński; author: Bartosz Dziewoński):

[mediawiki/extensions/VisualEditor@master] ApiParsoidTrait: Fix converting MessageValue to Message

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

You can reproduce the exception by attempting to view a visual diff of a translation page, for example: https://www.mediawiki.org/w/index.php?title=Help:Contents/pl&diff=prev&oldid=5597327&diffmode=visual

I couldn't find a way to reproduce locally without setting up the Translate extension.

After the patch, it fails with the error "Permission denied: stashbasehtml" rather than an exception (which isn't great, but it's probably a symptom of T350517).

Change 983942 merged by jenkins-bot:

[mediawiki/extensions/VisualEditor@master] ApiParsoidTrait: Fix converting MessageValue to Message

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