Page MenuHomePhabricator

RequestContext::importScopedSession fails in JobQueue when using --procs
Closed, ResolvedPublicBUG REPORT

Description

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

  • Translate an item of a translatable page (or create any kind of job that uses importScopedSession)
  • Execute job queue with --procs=2 (or higher)

What happens?:

2025-09-24 08:21:01 dev.translatewiki.net wiki: [c595566c8593a81ae87b3c87] [no req]   Wikimedia\Services\ContainerDisabledException: Container disabled!
#0 /srv/mediawiki/workdir/includes/MediaWikiServices.php(381): Wikimedia\Services\ServiceContainer->getService()
#1 /srv/mediawiki/workdir/vendor/wikimedia/services/src/ServiceContainer.php(414): MediaWiki\MediaWikiServices->getService()
#2 /srv/mediawiki/workdir/vendor/wikimedia/object-factory/src/ObjectFactory.php(204): Wikimedia\Services\ServiceContainer->get()
#3 /srv/mediawiki/workdir/vendor/wikimedia/object-factory/src/ObjectFactory.php(149): Wikimedia\ObjectFactory\ObjectFactory::getObjectFromSpec()
#4 /srv/mediawiki/workdir/includes/session/SessionManager.php(515): Wikimedia\ObjectFactory\ObjectFactory->createObject()
#5 /srv/mediawiki/workdir/includes/session/SessionManager.php(547): MediaWiki\Session\SessionManager->getProviders()
#6 /srv/mediawiki/workdir/includes/session/SessionManager.php(716): MediaWiki\Session\SessionManager->getProvider()
#7 /srv/mediawiki/workdir/includes/session/SessionManager.php(180): MediaWiki\Session\SessionManager->loadSessionInfoFromStore()
#8 /srv/mediawiki/workdir/includes/session/PHPSessionHandler.php(216): MediaWiki\Session\SessionManager->getSessionById()
#9 [internal function]: MediaWiki\Session\PHPSessionHandler->read()
#10 /srv/mediawiki/workdir/vendor/wikimedia/at-ease/src/AtEase.php(88): session_start()
#11 /srv/mediawiki/workdir/includes/context/RequestContext.php(737): Wikimedia\AtEase\AtEase::quietCall()
#12 /srv/mediawiki/workdir/includes/context/RequestContext.php(754): MediaWiki\Context\RequestContext::MediaWiki\Context\{closure}()
#13 /srv/mediawiki/workdir/extensions/Translate/src/PageTranslation/RenderTranslationPageJob.php(87): MediaWiki\Context\RequestContext::importScopedSession()
#14 /srv/mediawiki/workdir/includes/jobqueue/JobRunner.php(381): MediaWiki\Extension\Translate\PageTranslation\RenderTranslationPageJob->run()
#15 /srv/mediawiki/workdir/includes/jobqueue/JobRunner.php(339): MediaWiki\JobQueue\JobRunner->doExecuteJob()
#16 /srv/mediawiki/workdir/includes/jobqueue/JobRunner.php(234): MediaWiki\JobQueue\JobRunner->executeJob()
#17 /srv/mediawiki/workdir/maintenance/runJobs.php(107): MediaWiki\JobQueue\JobRunner->run()
#18 /srv/mediawiki/workdir/maintenance/includes/MaintenanceRunner.php(696): RunJobs->execute()
#19 /srv/mediawiki/workdir/maintenance/run.php(53): MediaWiki\Maintenance\MaintenanceRunner->run()
#20 /srv/mediawiki/workdir/maintenance/run(3): require(string)
#21 {main}

What should have happened instead?:

No exception.

Software version (on Special:Version page; skip for WMF-hosted wikis like Wikipedia):

Other information (browser name/version, screenshots, etc.):

Container disabled! exception appears because --procs parameter causes forking using ForkController, which calls \MediaWiki\Maintenance\ForkController::prepareEnvironment, which resets service container.

This is a problem because SessionManager(537) hold a reference to ObjectFactory that is now disabled.

Event Timeline

I cannot reproduce this error if I set $wgPHPSessionHandling = 'disable';. Could that be a workaround?

WebRequest::getSession() will cache the Session (which has a reference to the SessionBackend which has a reference to SessionManager which has a reference to ObjectFactory) on the request. Enabling PHP session handling will result in a bunch of pointless session checks so probably that caching happens sooner in the session lifecycle.

Conceptually the problem is that these cached references survive a container reset. I guess we should make SessionManager a destructible service and then have it un-cache all the request objects? Seems very messy.

(Arguably the real problem is that RequestContext should be cleared when the service container is reset, but that seems even more messy to do.)

I cannot reproduce this error if I set $wgPHPSessionHandling = 'disable';. Could that be a workaround?

This workaround does fix the issue, but setting it causes:

Some of your configuration settings caused a warning:

* PHPSessionHandling is deprecated: since 1.45 Integration with PHP session
 handling will be removed in the future

Please correct the issue before running update.php again.
If you know what you are doing, you can bypass this check
using --skip-config-validation.

Maybe the config variable shouldn't be deprecated before the default value is disable?

We are currently carrying a local patch to translatewiki that adds --skip-config-validation. We would prefer to drop it as soon as possible.

DAlangi_WMF changed the task status from Open to In Progress.Oct 31 2025, 2:08 PM
DAlangi_WMF claimed this task.

Change #1200358 had a related patch set uploaded (by D3r1ck01; author: Derick Alangi):

[mediawiki/core@master] session: Use fresh MW services container in CLI mode

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

The simplest workaround is probably defining the constant MW_NO_SESSION_HANDLER.

Change #1200358 merged by jenkins-bot:

[mediawiki/core@master] session: Use fresh MW services container in CLI mode

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

@Nikerabbit Can you confirm that this resolves the issue for you?

Reported too early, unfortunately the issue persists.

Reported too early, unfortunately the issue persists.

Ack! Will spend some time looking at that this week. Quick question, Nikerabbit: could you post me the latest stack trace if you have one? I'm unable to reproduce this error locally; however, I have another idea to do a follow-up. I want to be sure that the current occurrences have the same trace as before. Thanks!

Reported too early, unfortunately the issue persists.

Ack! Will spend some time looking at that this week. Quick question, Nikerabbit: could you post me the latest stack trace if you have one? I'm unable to reproduce this error locally; however, I have another idea to do a follow-up. I want to be sure that the current occurrences have the same trace as before. Thanks!

Very good point! It seems the trace has changed somewhat:

[2025-11-12T15:50:39.984787+00:00] exception.ERROR: [ced99b7e8fe1db6a1cc2dc15] [no req]   Wikimedia\Services\ContainerDisabledException: Container disabled! {"exception":"[object] (Wikimedia\\Services\\ContainerDisabledException(code: 0): Container disabled! at /srv/mediawiki/tags/2025-11-12_14:22:31/vendor/wikimedia/services/src/ServiceContainer.php:398)
[stacktrace]
#0 /srv/mediawiki/tags/2025-11-12_14:22:31/includes/MediaWikiServices.php(374): Wikimedia\\Services\\ServiceContainer->getService()
#1 /srv/mediawiki/tags/2025-11-12_14:22:31/vendor/wikimedia/services/src/ServiceContainer.php(414): MediaWiki\\MediaWikiServices->getService()
#2 /srv/mediawiki/tags/2025-11-12_14:22:31/vendor/wikimedia/object-factory/src/ObjectFactory.php(204): Wikimedia\\Services\\ServiceContainer->get()
#3 /srv/mediawiki/tags/2025-11-12_14:22:31/vendor/wikimedia/object-factory/src/ObjectFactory.php(149): Wikimedia\\ObjectFactory\\ObjectFactory::getObjectFromSpec()
#4 /srv/mediawiki/tags/2025-11-12_14:22:31/includes/Session/SessionManager.php(501): Wikimedia\\ObjectFactory\\ObjectFactory->createObject()
#5 /srv/mediawiki/tags/2025-11-12_14:22:31/includes/Session/SessionManager.php(533): MediaWiki\\Session\\SessionManager->getProviders()
#6 /srv/mediawiki/tags/2025-11-12_14:22:31/includes/Session/SessionManager.php(702): MediaWiki\\Session\\SessionManager->getProvider()
#7 /srv/mediawiki/tags/2025-11-12_14:22:31/includes/Session/SessionManager.php(166): MediaWiki\\Session\\SessionManager->loadSessionInfoFromStore()
#8 /srv/mediawiki/tags/2025-11-12_14:22:31/includes/Session/PHPSessionHandler.php(262): MediaWiki\\Session\\SessionManager->getSessionById()
#9 [internal function]: MediaWiki\\Session\\PHPSessionHandler->write()
#10 /srv/mediawiki/tags/2025-11-12_14:22:31/includes/Context/RequestContext.php(697): session_write_close()
#11 /srv/mediawiki/tags/2025-11-12_14:22:31/includes/Context/RequestContext.php(746): MediaWiki\\Context\\RequestContext::MediaWiki\\Context\\{closure}()
#12 [internal function]: MediaWiki\\Context\\RequestContext::MediaWiki\\Context\\{closure}()
#13 /srv/mediawiki/tags/2025-11-12_14:22:31/vendor/wikimedia/scoped-callback/src/ScopedCallback.php(102): call_user_func_array()
#14 /srv/mediawiki/tags/2025-11-12_14:22:31/vendor/wikimedia/scoped-callback/src/ScopedCallback.php(58): Wikimedia\\ScopedCallback->__destruct()
#15 /srv/mediawiki/tags/2025-11-12_14:22:31/extensions/Translate/src/PageTranslation/RenderTranslationPageJob.php(88): Wikimedia\\ScopedCallback::consume()
#16 /srv/mediawiki/tags/2025-11-12_14:22:31/includes/JobQueue/Job.php(353): MediaWiki\\Extension\\Translate\\PageTranslation\\RenderTranslationPageJob::MediaWiki\\Extension\\Translate\\PageTranslation\\{closure}()
#17 /srv/mediawiki/tags/2025-11-12_14:22:31/includes/JobQueue/JobRunner.php(388): MediaWiki\\JobQueue\\Job->teardown()
#18 /srv/mediawiki/tags/2025-11-12_14:22:31/includes/JobQueue/JobRunner.php(325): MediaWiki\\JobQueue\\JobRunner->doExecuteJob()
#19 /srv/mediawiki/tags/2025-11-12_14:22:31/includes/JobQueue/JobRunner.php(220): MediaWiki\\JobQueue\\JobRunner->executeJob()
#20 /srv/mediawiki/tags/2025-11-12_14:22:31/maintenance/runJobs.php(93): MediaWiki\\JobQueue\\JobRunner->run()
#21 /srv/mediawiki/tags/2025-11-12_14:22:31/maintenance/includes/MaintenanceRunner.php(696): RunJobs->execute()
#22 /srv/mediawiki/tags/2025-11-12_14:22:31/maintenance/run.php(53): MediaWiki\\Maintenance\\MaintenanceRunner->run()
#23 {main}
","exception_url":"[no req]","reqId":"ced99b7e8fe1db6a1cc2dc15","caught_by":"other"} []
[2025-11-12T15:51:52.402485+00:00] exception.ERROR: [5fc8c3b718046d5f3b7068ef] [no req]   BadMethodCallException: Sessions can only be imported when none is active. {"exception":"[object] (BadMethodCallException(code: 0): Sessions can only be imported when none is active. at /srv/mediawiki/tags/2025-11-12_14:22:31/includes/Context/RequestContext.php:672)
[stacktrace]
#0 /srv/mediawiki/tags/2025-11-12_14:22:31/extensions/Translate/src/PageTranslation/RenderTranslationPageJob.php(86): MediaWiki\\Context\\RequestContext::importScopedSession()
#1 /srv/mediawiki/tags/2025-11-12_14:22:31/includes/JobQueue/JobRunner.php(367): MediaWiki\\Extension\\Translate\\PageTranslation\\RenderTranslationPageJob->run()
#2 /srv/mediawiki/tags/2025-11-12_14:22:31/includes/JobQueue/JobRunner.php(325): MediaWiki\\JobQueue\\JobRunner->doExecuteJob()
#3 /srv/mediawiki/tags/2025-11-12_14:22:31/includes/JobQueue/JobRunner.php(220): MediaWiki\\JobQueue\\JobRunner->executeJob()
#4 /srv/mediawiki/tags/2025-11-12_14:22:31/maintenance/runJobs.php(93): MediaWiki\\JobQueue\\JobRunner->run()
#5 /srv/mediawiki/tags/2025-11-12_14:22:31/maintenance/includes/MaintenanceRunner.php(696): RunJobs->execute()
#6 /srv/mediawiki/tags/2025-11-12_14:22:31/maintenance/run.php(53): MediaWiki\\Maintenance\\MaintenanceRunner->run()
#7 {main}
","exception_url":"[no req]","reqId":"5fc8c3b718046d5f3b7068ef","caught_by":"other"} []

I suspected that. So it seems like there are more consumers of the SessionManager in this way, in addition to PHPSessionHandler::read(). We also have PHPSessionHandler::write() and PHPSessionHandler::destroy(). I'll centralize the logic for getting a new session manager object so that callers can use it. Thanks for posting the trace.

Change #1206817 had a related patch set uploaded (by D3r1ck01; author: Derick Alangi):

[mediawiki/core@master] session: Use fresh MW services container in CLI mode (take 2)

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

Change #1206817 merged by jenkins-bot:

[mediawiki/core@master] session: Use fresh MW services container in CLI mode (take 2)

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

Change #1206824 had a related patch set uploaded (by D3r1ck01; author: Derick Alangi):

[mediawiki/core@wmf/1.46.0-wmf.3] session: Use fresh MW services container in CLI mode (take 2)

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

@Nikerabbit, let me know if the issue persists for you. Thanks!

Big thanks. We have a regular twn deployment tomorrow. I'll report after that.

Change #1206824 abandoned by D3r1ck01:

[mediawiki/core@wmf/1.46.0-wmf.3] session: Use fresh MW services container in CLI mode (take 2)

Reason:

Not needed.

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

Big thanks. We have a regular twn deployment tomorrow. I'll report after that.

@Nikerabbit Have you had time to check it?

Seems to work now. Thanks!

Thanks for confirming @Nikerabbit and resolving this as done now.

Change #1211024 had a related patch set uploaded (by Bartosz Dziewoński; author: Derick Alangi):

[mediawiki/core@REL1_45] session: Use fresh MW services container in CLI mode

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

Change #1211025 had a related patch set uploaded (by Bartosz Dziewoński; author: Derick Alangi):

[mediawiki/core@REL1_45] session: Use fresh MW services container in CLI mode (take 2)

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

Change #1211024 merged by jenkins-bot:

[mediawiki/core@REL1_45] session: Use fresh MW services container in CLI mode

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

Change #1211025 merged by jenkins-bot:

[mediawiki/core@REL1_45] session: Use fresh MW services container in CLI mode (take 2)

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