Page MenuHomePhabricator

[M] Sporadic “TypeError: Return value of EntityContentFactory::getTitleForId() must be an instance of Title, null returned” for Special:EntityData on Commons
Open, Needs TriagePublicPRODUCTION ERROR

Description

Error message
Return value of Wikibase\Repo\Content\EntityContentFactory::getTitleForId() must be an instance of Title, null returned
Stack Trace
	
from /srv/mediawiki/php-1.36.0-wmf.28/extensions/Wikibase/repo/includes/Content/EntityContentFactory.php(134)
#0 /srv/mediawiki/php-1.36.0-wmf.28/extensions/Wikibase/repo/includes/Store/TypeDispatchingEntityTitleStoreLookup.php(44): Wikibase\Repo\Content\EntityContentFactory->getTitleForId(Wikibase\MediaInfo\DataModel\MediaInfoId)
#1 /srv/mediawiki/php-1.36.0-wmf.28/extensions/Wikibase/repo/includes/LinkedData/EntityDataUriManager.php(151): Wikibase\Repo\Store\TypeDispatchingEntityTitleStoreLookup->getTitleForId(Wikibase\MediaInfo\DataModel\MediaInfoId)
#2 /srv/mediawiki/php-1.36.0-wmf.28/extensions/Wikibase/repo/includes/LinkedData/EntityDataUriManager.php(182): Wikibase\Repo\LinkedData\EntityDataUriManager->getDocTitle(Wikibase\MediaInfo\DataModel\MediaInfoId, string)
#3 /srv/mediawiki/php-1.36.0-wmf.28/extensions/Wikibase/repo/includes/LinkedData/EntityDataRequestHandler.php(356): Wikibase\Repo\LinkedData\EntityDataUriManager->getDocUrl(Wikibase\MediaInfo\DataModel\MediaInfoId, string, integer)
#4 /srv/mediawiki/php-1.36.0-wmf.28/extensions/Wikibase/repo/includes/LinkedData/EntityDataRequestHandler.php(234): Wikibase\Repo\LinkedData\EntityDataRequestHandler->httpContentNegotiation(WebRequest, OutputPage, Wikibase\MediaInfo\DataModel\MediaInfoId, integer)
#5 /srv/mediawiki/php-1.36.0-wmf.28/extensions/Wikibase/repo/includes/Specials/SpecialEntityData.php(118): Wikibase\Repo\LinkedData\EntityDataRequestHandler->handleRequest(string, WebRequest, OutputPage)
#6 /srv/mediawiki/php-1.36.0-wmf.28/includes/specialpage/SpecialPage.php(645): Wikibase\Repo\Specials\SpecialEntityData->execute(string)
#7 /srv/mediawiki/php-1.36.0-wmf.28/includes/specialpage/SpecialPageFactory.php(1405): SpecialPage->run(string)
#8 /srv/mediawiki/php-1.36.0-wmf.28/includes/MediaWiki.php(310): MediaWiki\SpecialPage\SpecialPageFactory->executePath(Title, RequestContext)
#9 /srv/mediawiki/php-1.36.0-wmf.28/includes/MediaWiki.php(944): MediaWiki->performRequest()
#10 /srv/mediawiki/php-1.36.0-wmf.28/includes/MediaWiki.php(548): MediaWiki->main()
#11 /srv/mediawiki/php-1.36.0-wmf.28/index.php(53): MediaWiki->run()
#12 /srv/mediawiki/php-1.36.0-wmf.28/index.php(46): wfIndexMain()
#13 /srv/mediawiki/w/index.php(3): require(string)
#14 {main}
Impact

Low – 37 messages over the past 30 days (mostly after 2020-01-27).

Notes

Only seems to affect Commons, with Special:EntityData/M... titles. Also, for the few instances I’ve tested so far, plugging the page ID from the request title into index.php?curid= (example link) yields a “bad title” error (“The requested page title is empty or contains only the name of a namespace.”).

Details

Request ID
YBgxdApAAEUAAHWbUJwAAAAK
Request URL
https://commons.wikimedia.org/wiki/Special:EntityData/M96853506

Related Objects

StatusSubtypeAssignedTask
Declineddchen
OpenNone
OpenNone
DuplicateNone
OpenNone
OpenNone
OpenNone
StalledNone
DuplicateNone
OpenNone
ResolvedNone
OpenNone
OpenNone
OpenNone
OpenNone
Resolvedppelberg
ResolvedKrinkle
OpenNone
ResolvedNone
ResolvedNone
StalledNone
OpenNone
OpenNone
Opendaniel
OpenNone
OpenNone
OpenNone
OpenNone
Resolveddaniel
Opendaniel
Resolveddaniel
OpenPRODUCTION ERRORNone

Event Timeline

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

Apparently those page IDs simply don’t exist, and this TypeError happens with any nonexistent page ID, e.g. Special:EntityData/M4 or M13.

Ah, I wondered why it only started happening recently. Thanks.

Not sure what to do here, to be honest. EntityContentFactory::getTitle() is allowed to return null, according to the interface it implements:

interface EntityTitleLookup {

	/**
	 * Returns the Title for the given entity.
	 *
	 * If the entity does not exist, this method will return either null,
	 * or a Title object referring to a page that does not exist.
	 *
	 * @todo change this to return a TitleValue
	 *
	 * @param EntityId $id
	 *
	 * @throws MWException
	 * @throws OutOfBoundsException
	 * @throws InvalidArgumentException
	 * @return Title|null
	 */
	public function getTitleForId( EntityId $id );

But just changing the return type wouldn’t fix this issue, because the callers in EntityDataUriManager and EntityDataRequestHandler expect this method to return a non-null Title that they can call getFullURL() on, to redirect the request to that URL. I’m guessing this used to work out by redirecting to index.php?curid=<nonexistent>, and we can’t do that anymore.

This also happens if the URL ends in .html, by the way, because that also triggers content negotiation. With other formats, such as .json, it correctly shows an error message that no such entity exists.

I suppose EntityDataUriManager and EntityDataRequestHandler need to be taught that not every entity type can always redirect to a wiki page for a certain entity.

@CBogen @MarkTraceur can your team take care of this issue, since it seems to only affect Structured Data on Commons? (Apologies if I’m pinging the wrong people.)

@CBogen @MarkTraceur can your team take care of this issue, since it seems to only affect Structured Data on Commons? (Apologies if I’m pinging the wrong people.)

Thanks @Lucas_Werkmeister_WMDE. We'll put it through our normal estimation and prioritization process.

CBogen renamed this task from Sporadic “TypeError: Return value of EntityContentFactory::getTitleForId() must be an instance of Title, null returned” for Special:EntityData on Commons to [M] Sporadic “TypeError: Return value of EntityContentFactory::getTitleForId() must be an instance of Title, null returned” for Special:EntityData on Commons.Feb 9 2021, 5:22 PM

Estimating as medium, but if investigation goes beyond a medium effort, we will re-evaluate.

The problem is that MediaInfoHandler::getTitleForId is declared (and can) return null, but the parent EntityHandler::getTitleForId is not declared to return null.
That means all the code depending on EntityHandler like the EntityContentFactory does not handle the null and failing.

What for a Title could be created to fall back for non-existing MediaInfoIds?
Or should EntityHandler::getTitleForId allow null? It is not the implementation for EntityTitleLookup::getTitleForId which allows null, because EntityHandler is not a lookup, even it is mention with @see in that function.

I suspect the correct solution within MediaInfoHandler::getTitleForId would probable be to throw an InvalidArgumentException in case there's no title for the given id (EntityHandler::getTitleForId is documented to throw that exception if $id refers to an entity of the wrong type.)

That, and whatever code path (EntityDataUriManager::getDocTitle?) currently ends up calling it with such invalid entity id should probably be be updated to catch that exception (or not allow triggering it in the first place) and handle it more gracefully (unless that exception is already being caught, but the TypeError prevents it from getting there)

Change 667684 had a related patch set uploaded (by Umherirrender; owner: Umherirrender):
[mediawiki/extensions/Wikibase@master] Fix null return type hint for EntityContentFactory::getTitleForId

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

Change 667685 had a related patch set uploaded (by Umherirrender; owner: Umherirrender):
[mediawiki/extensions/WikibaseMediaInfo@master] Fix return type for MediaInfoHandler::getTitleForId

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

Patches LGTM, but I didn't +2 the one in Wikibase repo (so that WMDE can look it over & approve)
If they prefer me to +2, LMK, would be happy to.

Change 667684 merged by jenkins-bot:
[mediawiki/extensions/Wikibase@master] Fix null return type hint for EntityContentFactory::getTitleForId

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

Change 667685 merged by jenkins-bot:
[mediawiki/extensions/WikibaseMediaInfo@master] Fix return type for MediaInfoHandler::getTitleForId

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