Page MenuHomePhabricator

Error: Call to a member function getPageAsLinkTarget() on null
Open, LowPublicPRODUCTION ERROR

Description

This is a series of three issues, which all seem related: a warning, a notice, and finally an error.

Error
The warning on line 102
PHP Warning: explode() expects parameter 2 to be string, object given
The notice on line 107
PHP Notice: Trying to access array offset on value of type null

And then the full error:

normalized_message
[{reqId}] {exception_url}   Error: Call to a member function getPageAsLinkTarget() on null
exception.trace
from /srv/mediawiki/php-1.43.0-wmf.10/extensions/EventLogging/includes/JsonSchemaContent.php(109)
#0 /srv/mediawiki/php-1.43.0-wmf.10/includes/content/JsonContent.php(112): MediaWiki\Extension\EventLogging\JsonSchemaContent->objectRow(string, stdClass)
#1 /srv/mediawiki/php-1.43.0-wmf.10/includes/content/JsonContent.php(186): MediaWiki\Content\JsonContent->objectTable(stdClass)
#2 /srv/mediawiki/php-1.43.0-wmf.10/includes/content/JsonContent.php(137): MediaWiki\Content\JsonContent->valueCell(stdClass)
#3 /srv/mediawiki/php-1.43.0-wmf.10/extensions/EventLogging/includes/JsonSchemaContent.php(117): MediaWiki\Content\JsonContent->objectRow(string, stdClass)
#4 /srv/mediawiki/php-1.43.0-wmf.10/includes/content/JsonContent.php(112): MediaWiki\Extension\EventLogging\JsonSchemaContent->objectRow(string, stdClass)
#5 /srv/mediawiki/php-1.43.0-wmf.10/includes/content/JsonContent.php(83): MediaWiki\Content\JsonContent->objectTable(stdClass)
#6 /srv/mediawiki/php-1.43.0-wmf.10/includes/content/JsonContentHandler.php(127): MediaWiki\Content\JsonContent->rootValueTable(stdClass)
#7 /srv/mediawiki/php-1.43.0-wmf.10/extensions/EventLogging/includes/JsonSchemaContentHandler.php(55): MediaWiki\Content\JsonContentHandler->fillParserOutput(MediaWiki\Extension\EventLogging\JsonSchemaContent, MediaWiki\Content\Renderer\ContentParseParams, MediaWiki\Parser\ParserOutput)
#8 /srv/mediawiki/php-1.43.0-wmf.10/includes/content/ContentHandler.php(1674): MediaWiki\Extension\EventLogging\JsonSchemaContentHandler->fillParserOutput(MediaWiki\Extension\EventLogging\JsonSchemaContent, MediaWiki\Content\Renderer\ContentParseParams, MediaWiki\Parser\ParserOutput)
#9 /srv/mediawiki/php-1.43.0-wmf.10/includes/content/Renderer/ContentRenderer.php(67): ContentHandler->getParserOutput(MediaWiki\Extension\EventLogging\JsonSchemaContent, MediaWiki\Content\Renderer\ContentParseParams)
#10 /srv/mediawiki/php-1.43.0-wmf.10/includes/Revision/RenderedRevision.php(260): MediaWiki\Content\Renderer\ContentRenderer->getParserOutput(MediaWiki\Extension\EventLogging\JsonSchemaContent, MediaWiki\Title\Title, MediaWiki\Revision\RevisionStoreRecord, ParserOptions, boolean)
#11 /srv/mediawiki/php-1.43.0-wmf.10/includes/Revision/RenderedRevision.php(232): MediaWiki\Revision\RenderedRevision->getSlotParserOutputUncached(MediaWiki\Extension\EventLogging\JsonSchemaContent, boolean)
#12 /srv/mediawiki/php-1.43.0-wmf.10/includes/Revision/RevisionRenderer.php(226): MediaWiki\Revision\RenderedRevision->getSlotParserOutput(string, array)
#13 /srv/mediawiki/php-1.43.0-wmf.10/includes/Revision/RevisionRenderer.php(164): MediaWiki\Revision\RevisionRenderer->combineSlotOutput(MediaWiki\Revision\RenderedRevision, ParserOptions, array)
#14 [internal function]: MediaWiki\Revision\RevisionRenderer->MediaWiki\Revision\{closure}(MediaWiki\Revision\RenderedRevision, array)
#15 /srv/mediawiki/php-1.43.0-wmf.10/includes/Revision/RenderedRevision.php(199): call_user_func(Closure, MediaWiki\Revision\RenderedRevision, array)
#16 /srv/mediawiki/php-1.43.0-wmf.10/includes/page/ParserOutputAccess.php(381): MediaWiki\Revision\RenderedRevision->getRevisionParserOutput()
#17 /srv/mediawiki/php-1.43.0-wmf.10/includes/page/ParserOutputAccess.php(332): MediaWiki\Page\ParserOutputAccess->renderRevision(WikiPage, ParserOptions, MediaWiki\Revision\RevisionStoreRecord, integer)
#18 /srv/mediawiki/php-1.43.0-wmf.10/includes/content/ContentHandler.php(1451): MediaWiki\Page\ParserOutputAccess->getParserOutput(WikiPage, ParserOptions, MediaWiki\Revision\RevisionStoreRecord, integer)
#19 /srv/mediawiki/php-1.43.0-wmf.10/extensions/CirrusSearch/includes/BuildDocument/ParserOutputPageProperties.php(86): ContentHandler->getParserOutputForIndexing(WikiPage, NULL, MediaWiki\Revision\RevisionStoreRecord)
#20 /srv/mediawiki/php-1.43.0-wmf.10/includes/libs/objectcache/wancache/WANObjectCache.php(1726): CirrusSearch\BuildDocument\ParserOutputPageProperties->CirrusSearch\BuildDocument\{closure}(boolean, integer, array, NULL, array)
#21 /srv/mediawiki/php-1.43.0-wmf.10/includes/libs/objectcache/wancache/WANObjectCache.php(1556): WANObjectCache->fetchOrRegenerate(string, integer, Closure, array, array)
#22 /srv/mediawiki/php-1.43.0-wmf.10/extensions/CirrusSearch/includes/BuildDocument/ParserOutputPageProperties.php(95): WANObjectCache->getWithSetCallback(string, integer, Closure)
#23 /srv/mediawiki/php-1.43.0-wmf.10/extensions/CirrusSearch/includes/BuildDocument/ParserOutputPageProperties.php(51): CirrusSearch\BuildDocument\ParserOutputPageProperties->finalizeReal(Elastica\Document, WikiPage, CirrusSearch\CirrusSearch, MediaWiki\Revision\RevisionStoreRecord)
#24 /srv/mediawiki/php-1.43.0-wmf.10/extensions/CirrusSearch/includes/BuildDocument/BuildDocument.php(196): CirrusSearch\BuildDocument\ParserOutputPageProperties->finalize(Elastica\Document, MediaWiki\Title\Title, MediaWiki\Revision\RevisionStoreRecord)
#25 /srv/mediawiki/php-1.43.0-wmf.10/extensions/CirrusSearch/includes/Api/QueryBuildDocument.php(106): CirrusSearch\BuildDocument\BuildDocument->finalize(Elastica\Document, boolean, MediaWiki\Revision\RevisionStoreRecord)
#26 /srv/mediawiki/php-1.43.0-wmf.10/includes/api/ApiQuery.php(706): CirrusSearch\Api\QueryBuildDocument->execute()
#27 /srv/mediawiki/php-1.43.0-wmf.10/includes/api/ApiMain.php(1952): ApiQuery->execute()
#28 /srv/mediawiki/php-1.43.0-wmf.10/includes/api/ApiMain.php(928): ApiMain->executeAction()
#29 /srv/mediawiki/php-1.43.0-wmf.10/includes/api/ApiMain.php(899): ApiMain->executeActionWithErrorHandling()
#30 /srv/mediawiki/php-1.43.0-wmf.10/includes/api/ApiEntryPoint.php(158): ApiMain->execute()
#31 /srv/mediawiki/php-1.43.0-wmf.10/includes/MediaWikiEntryPoint.php(200): MediaWiki\Api\ApiEntryPoint->execute()
#32 /srv/mediawiki/php-1.43.0-wmf.10/api.php(44): MediaWiki\MediaWikiEntryPoint->run()
#33 /srv/mediawiki/w/api.php(3): require(string)
#34 {main}
Impact

Logspam, invalid API responses, and (I think) failure to index some content? (Judging by prop=cirrusbuilddoc.)

Notes

Details

Request URL
https://meta.wikimedia.org/w/api.php?action=query&format=json&cbbuilders=content%7Clinks&prop=cirrusbuilddoc&formatversion=2&format=json&revids=27016577

Event Timeline

Restricted Application added a subscriber: Aklapper. · View Herald Transcript

I’m not really sure how this code could ever have worked:

includes/JsonSchemaContent.php
	public function objectRow( $key, $val ) {
		if ( $key === '$ref' ) {
			$valParts = explode( '/', $val, 2 );
			if ( !isset( $valParts[1] ) ) {
				// Don't store or inject service objects in Content objects
				// as that breaks serialization (T286610).
				$services = MediaWikiServices::getInstance();
				$revId = (int)$valParts[1];
				$revRecord = $services->getRevisionLookup()->getRevisionById( $revId );
				$title = $revRecord->getPageAsLinkTarget();

We’ve already checked that $valParts[1] isn’t set, but then we still cast it to an int, and try to load a revision record from that ID? Is the if condition just flipped from what it should be?

I also don’t see any recent changes to the code, which is confusing.

Ottomata subscribed.

FWIW, we are SO CLOSE to not needing EventLogging\JsonSchemaContent for WMF purposes. Once T353817 is done, we can do T238230, which will remove WMF usage of EventLogging on wiki JSONSchemas.

Adding Search since this seems to be triggered from CirrusSearch?

We’ve already checked that $valParts[1] isn’t set, but then we still cast it to an int, and try to load a revision record from that ID? Is the if condition just flipped from what it should be?

yes I don't see how this could ever have worked, it is possible that this problem was somehow hidden by other problems like T286610 that got fixed recently?

The problem appears to have been highlighted by this edit to the Schema schema.

I’m not really sure how this code could ever have worked:

includes/JsonSchemaContent.php
	public function objectRow( $key, $val ) {
		if ( $key === '$ref' ) {
			$valParts = explode( '/', $val, 2 );
			if ( !isset( $valParts[1] ) ) {
				// Don't store or inject service objects in Content objects
				// as that breaks serialization (T286610).
				$services = MediaWikiServices::getInstance();
				$revId = (int)$valParts[1];
				$revRecord = $services->getRevisionLookup()->getRevisionById( $revId );
				$title = $revRecord->getPageAsLinkTarget();

We’ve already checked that $valParts[1] isn’t set, but then we still cast it to an int, and try to load a revision record from that ID? Is the if condition just flipped from what it should be?

I also don’t see any recent changes to the code, which is confusing.

Also, the $val parameter is documented as mixed. It can sometimes be an stdClass instance. This will trigger an error when it's passed to explode().

@phuedx and @Ottomata what are next steps for this? Is the work actively happening T353817: Create legacy EventLogging proxy HTTP intake (for MediaWikiPingback) endpoint to EventGate the next step? is there a timeline for it?

@Lucas_Werkmeister_WMDE is this blocking anything urgent on your end?

Is the work actively happening T353817: Create legacy EventLogging proxy HTTP intake (for MediaWikiPingback) endpoint to EventGate the next step?

No, this task (T368543) is about the PHP MediaWiki EventLogging extension doing something bad.

However, once T353817 and T238230: Decommission EventLogging backend components by migrating to MEP are done, WMF will have no need or usage of the offending JsonSchemaContent.php and related features. From our perspective we could just remove the feature and code from EventLogging extension.

I suspect that EventLogging may used by 3rd parties though. Removing the JsonSchemaContent feature from it may be controversial.

So I think: JsonSchemaContent feature in EventLogging extension has no owner?

@Lucas_Werkmeister_WMDE is this blocking anything urgent on your end?

Not at all, I just saw it in the logs (probably while deploying, though I don’t exactly remember).

Still an issue in 1.43.0-wmf.19 in the logs

Still an issue in 1.43.0-wmf.26 in the logs. Does Data-Engineering triage its tickets?

Change #1079225 had a related patch set uploaded (by Phuedx; author: Phuedx):

[mediawiki/extensions/EventLogging@master] jsonschemacontent: Fix objectRow "$ref" handling

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

There were 25 errors in the last two weeks. I'm going to be bold and assign this Low priority.