In `Parser::braceSubstitution()`, the block that handles transcluded special pages does this:
```lang=php
// Create a new context to execute the special page
$context = new RequestContext;
$context->setTitle( $title );
$context->setRequest( new FauxRequest( $pageArgs ) );
if ( $specialPage && $specialPage->maxIncludeCacheTime() === 0 ) {
$context->setUser( $this->userFactory->newFromUserIdentity( $this->getUserIdentity() ) );
} else {
// If this page is cached, then we better not be per user.
$context->setUser( User::newFromName( '127.0.0.1', false ) );
}
$context->setLanguage( $this->mOptions->getUserLangObj() );
$ret = $this->specialPageFactory->capturePath( $title, $context, $this->getLinkRenderer() );
```
and then `SpecialPage::capturePath()` does this:
```lang=php
$main = RequestContext::getMain();
$ctx = [
'title' => $main->getTitle(),
'output' => $main->getOutput(),
'request' => $main->getRequest(),
'user' => $main->getUser(),
'language' => $main->getLanguage(),
];
// Override
$main->setTitle( $title );
$main->setOutput( $context->getOutput() );
$main->setRequest( $context->getRequest() );
$main->setUser( $context->getUser() );
$main->setLanguage( $context->getLanguage() );
// The useful part
$ret = $this->executePath( $page, $context, true, $linkRenderer );
// Restore old globals and context
$main->setTitle( $ctx['title'] );
$main->setOutput( $ctx['output'] );
$main->setRequest( $ctx['request'] );
$main->setUser( $ctx['user'] );
$main->setLanguage( $ctx['language'] );
```
This was a hacky but reasonably safe thing to do in the past. But in a service container based world, where services can are created on the fly and stored for future invocations, and dependencies get passed in, all these things might get cached in various places. The one I ran into was `MinervaHooks::onSpecialPageBeforeExecute()` fetching the `Vector.FeatureManager` service, which is initialized using the request context; it ends up storing the FauxRequest created by the parser and so you get a weird failure of the `useskinversion` URL parameter on some pages.
That specific bug is very fringe and is not worth much attention, but the trick employed by the parser could be the source of other bugs and it might be worth thinking about how to move away from this pattern.