Page MenuHomePhabricator

Wikimedia\Assert\ParameterAssertionException: Bad value for parameter $link: namespace must not be virtual
Closed, ResolvedPublicPRODUCTION ERROR

Description

Error
  • mwversion: Seen since 1.38.0-wmf.22, but this is a report from wmf.24
  • reqId: bafd5042-ab9e-4b6e-bbb2-c69b8f16457e
  • Find reqId in Logstash
normalized_message
[{reqId}] {exception_url}   Wikimedia\Assert\ParameterAssertionException: Bad value for parameter $link: namespace must not be virtual
exception.trace
from /srv/mediawiki/php-1.38.0-wmf.24/vendor/wikimedia/assert/src/Assert.php(72)
#0 /srv/mediawiki/php-1.38.0-wmf.24/includes/page/PageStore.php(121): Wikimedia\Assert\Assert::parameter(boolean, string, string)
#1 /srv/mediawiki/php-1.38.0-wmf.24/includes/Rest/Handler/SearchHandler.php(259): MediaWiki\Page\PageStore->getPageForLink(Title)
#2 /srv/mediawiki/php-1.38.0-wmf.24/includes/Rest/Handler/SearchHandler.php(225): MediaWiki\Rest\Handler\SearchHandler->buildSinglePage(Title, SearchSuggestion)
#3 /srv/mediawiki/php-1.38.0-wmf.24/includes/Rest/Handler/SearchHandler.php(185): MediaWiki\Rest\Handler\SearchHandler->buildPageObjects(array)
#4 /srv/mediawiki/php-1.38.0-wmf.24/includes/Rest/Handler/SearchHandler.php(371): MediaWiki\Rest\Handler\SearchHandler->doSearch(CirrusSearch\CirrusSearch)
#5 /srv/mediawiki/php-1.38.0-wmf.24/includes/Rest/Router.php(414): MediaWiki\Rest\Handler\SearchHandler->execute()
#6 /srv/mediawiki/php-1.38.0-wmf.24/includes/Rest/Router.php(338): MediaWiki\Rest\Router->executeHandler(MediaWiki\Rest\Handler\SearchHandler)
#7 /srv/mediawiki/php-1.38.0-wmf.24/includes/Rest/EntryPoint.php(167): MediaWiki\Rest\Router->execute(MediaWiki\Rest\RequestFromGlobals)
#8 /srv/mediawiki/php-1.38.0-wmf.24/includes/Rest/EntryPoint.php(132): MediaWiki\Rest\EntryPoint->execute()
#9 /srv/mediawiki/php-1.38.0-wmf.24/rest.php(31): MediaWiki\Rest\EntryPoint::main()
#10 /srv/mediawiki/w/rest.php(3): require(string)
#11 {main}
Impact

Low frequency but persistent log noise

Notes

Started 2022-02-16, during wmf.22.

Details

Request URL
https://fa.wikipedia.org/w/rest.php/v1/search/title?q=*&limit=*
Related Changes in Gerrit:

Event Timeline

This ticket was discussed and semi-debugged in an ad-hoc thread on slack.
The outcome is to complete T301346 which would include Special pages in search results (as this bug is coming from searching for a redirect page that is a Special page)

Also seeing, with a different message tail, but I'm assuming the same cause:

Error
normalized_message
[{reqId}] {exception_url}   Wikimedia\Assert\ParameterAssertionException: Bad value for parameter $link: must not be external
exception.trace
from /srv/mediawiki/php-1.38.0-wmf.25/vendor/wikimedia/assert/src/Assert.php(72)
#0 /srv/mediawiki/php-1.38.0-wmf.25/includes/page/PageStore.php(111): Wikimedia\Assert\Assert::parameter(boolean, string, string)
#1 /srv/mediawiki/php-1.38.0-wmf.25/includes/Rest/Handler/SearchHandler.php(259): MediaWiki\Page\PageStore->getPageForLink(Title)
#2 /srv/mediawiki/php-1.38.0-wmf.25/includes/Rest/Handler/SearchHandler.php(225): MediaWiki\Rest\Handler\SearchHandler->buildSinglePage(Title, SearchSuggestion)
#3 /srv/mediawiki/php-1.38.0-wmf.25/includes/Rest/Handler/SearchHandler.php(185): MediaWiki\Rest\Handler\SearchHandler->buildPageObjects(array)
#4 /srv/mediawiki/php-1.38.0-wmf.25/includes/Rest/Handler/SearchHandler.php(371): MediaWiki\Rest\Handler\SearchHandler->doSearch(CirrusSearch\CirrusSearch)
#5 /srv/mediawiki/php-1.38.0-wmf.25/includes/Rest/Router.php(414): MediaWiki\Rest\Handler\SearchHandler->execute()
#6 /srv/mediawiki/php-1.38.0-wmf.25/includes/Rest/Router.php(338): MediaWiki\Rest\Router->executeHandler(MediaWiki\Rest\Handler\SearchHandler)
#7 /srv/mediawiki/php-1.38.0-wmf.25/includes/Rest/EntryPoint.php(167): MediaWiki\Rest\Router->execute(MediaWiki\Rest\RequestFromGlobals)
#8 /srv/mediawiki/php-1.38.0-wmf.25/includes/Rest/EntryPoint.php(132): MediaWiki\Rest\EntryPoint->execute()
#9 /srv/mediawiki/php-1.38.0-wmf.25/rest.php(31): MediaWiki\Rest\EntryPoint::main()
#10 /srv/mediawiki/w/rest.php(3): require(string)
#11 {main}
Krinkle triaged this task as High priority.Mar 14 2022, 4:24 PM
Krinkle moved this task from Untriaged to Mar 2022 on the Wikimedia-production-error board.

There are two versions of this issue, both of which were caused by the same change to introduce redirect resolutions:

  • Bad value for parameter $link: namespace must not be virtual

This seems to happen when the value (or its destination) is a special page. I suspect this has since been fixed by the subsequent patches at T301346. At least I can't trivially reproduce this on fr.wikipedia.org today when searching for Special:. I don't know if that's the way it used to happen though. To be confirmed by @nnikkhoui.

  • Bad value for parameter $link: must not be external

This happens when the redirect destination is an interwiki. The example in our error logs is as follows:

  1. https://foundation.wikimedia.org/wiki/Privacy_policy (a popular page)
  2. Search for thanks, which should yield the local page called [[Thanks]]. Except, this is a redirect to donate:Thank You, which cannot be expressed as a local page identity.

This is still failing today, e.g. at https://foundation.wikimedia.org/w/rest.php/v1/search/title?q=thanks&limit=10.

This seems to happen when the value (or its destination) is a special page.

Yes. This error was when the redirect was to a Special page, to be fixed by the patch at T301346 as @Krinkle stated.

This happens when the redirect destination is an interwiki.

Thanks for raising this one. I had a question about this I brought up with @daniel. Since the behavior for interwiki links changes based on configuration ($wgDisableHardRedirects) Im wondering if expected behaviour should mirror the user experience. For example, should we check that an interwiki link is local before we make the result point to the redirect target?

[…]

This happens when the redirect destination is an interwiki.

Thanks for raising this one. I had a question about this I brought up with @daniel. Since the behavior for interwiki links changes based on configuration ($wgDisableHardRedirects) Im wondering if expected behaviour should mirror the user experience. For example, should we check that an interwiki link is local before we make the result point to the redirect target?

For context - This isn't a problem in the default opensearch UI because we don't resolve redirects, and interwiki links themselves are never suggested as they are not titles on the local wiki that we autocomplete through there. It's only an issue when there is a local match which then points elsewhere.

From there, it is then the pageview handling responsibility to decide what to do upon visiting /wiki/someting:Elsewhere. The resolution and serving of a redirect is non-trivial. There is much business logic, performance and security, concerns and other complexity around this. This code lives mostly in the main MediaWiki.php class, which is where index.php routes are handled. The main thing to take away from this is that we have Special:GoToInterwiki, which provides an interstitial for cases like this where we cannot place responsibility on the consuming user interface as we have already gone past it. This special page provide a way to still return a stable URL to answer such request, and yet also don't break security and privacy expectations (more context at T122209).

To answer your question - Yes, I think we'd want to check for that, if we are resolving the redirect. Navigating to such link would otherwise leak the user's PII to a third-party, which the interface would not have warned or indicated in that context. Upon plain form submission (no suggestion clicked), we redirect to the top entry, but never for external redirects. I think for pressing enter when the UI may have selected the first suggestion is essentially the same interaction and equally lacking context or informed consent.

Considering the amount of logic involved, I would recommend disposing the redirect target if it is unusual in any way and instead return the same as the status quo, treating it as if it weren't a redirect. If we have a search suggestion "Foo" that redirects to a special page, or local interwiki, or external interwiki; just return as if it was a normal page "Foo", then the pageview handler on the other end can deal with the security implications of redirecting to a special page (which is almost never allowed, e.g. imagine a redirect to Special:Logout, or other clever unexpected destinations inserted between genuine article destinations), and with the resolution of all forms of interwikis.

Considering the amount of logic involved, I would recommend disposing the redirect target if it is unusual in any way and instead return the same as the status quo

Thanks for brining up all those points @Krinkle. I think youre recommendation makes the most sense, I don't want to place the logic of Special:GoToInterwiki on the REST endpoint, I will take your suggestion and just return the regular page as the result, and then once the user clicks on that page, get redirected as they usually would.

Change 762945 had a related patch set uploaded (by Nikki Nikkhoui; author: Nikki Nikkhoui):

[mediawiki/core@master] Include Special pages in Search Results

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

Change 762945 merged by jenkins-bot:

[mediawiki/core@master] Include Special pages in Search Results

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

Should be fixed now!