Problem/Motivation
The problem I encountered occurred when I was attempting to update from Drupal core 9.2.10 to Drupal core 9.3.2. It fails on the "drush updatedb" command and the site becomes unusable. Rolling back the updates with composer doesn't fix the problem as has been done on other update testing. Once the "drush updatedb" command is executed after the Drupal core and the sqlsrv module are updated, the site becomes un-recoverable without restoring a previous version of the DB.
After I ran into this error, I found one Drupal issue with the same basic problem (search_api issue 3256944). But it appeared for a specific contributed module. So, I'm posting this issue for the core level as it appears the problem affects basic user related stuff.
Steps to reproduce
Our website configurations as of 2021-12-22:
- Operating System: Windows 10 Enterprise and Windows Server 2012 R2 Standard (both are 64-bit)
- Web server: Apache 2.4.51 (64-bit) using mod_fcgid for PHP
- PHP version: PHP 8.0.13 (64-bit, non-threadsafe)
- Database: Microsoft SQL Server Enterprise 14.0.3048.4 (64-bit)
- Drupal version: 9.2.10
- Drupal driver for SQL Server and SQL Azure: 4.2.3
- PHP to SQL Server driver: 5.9.0 from https://pecl.php.net/ for sqlsrv and pdo_sqlsrv
We started using earlier, stable versions of all of the above in 2016 and have kept them all as current as possible.
We updated to Drupal 9.2.10 from an earlier 9.2 version on 2021-12-22 using composer and had no issues then or since.
We have been using the "Drupal driver for SQL Server and SQL Azure" project to interface between MS SQL Server and Drupal. Drupal 9.3 required version 4.3.1 and I attempted to update with that as well. All the composer update operations finished without errors.
This is the sequence of commands processed before the failure happened:
composer global update
drush -y config-set system.performance css.preprocess 0
drush -y config-set system.performance js.preprocess 0
drush cache:rebuild
composer require drupal/core-recommended:^9.3.2 drupal/core-dev:^9.3.2 drupal/core-composer-scaffold:^9.3.2 drupal/core-project-message:^9.3.2 drupal/core-vendor-hardening:^9.3.2 drush/drush drupal/devel composer/installers --update-with-dependencies
composer require drupal/sqlsrv:^4.3.1
drush updatedb
The output from the updatedb command:
Do you wish to run the specified pending updates? (yes/no) [yes]:
> yes
> [notice] Update started: user_update_9301
> [notice] Update completed: user_update_9301
> [notice] Update started: block_post_update_replace_node_type_condition
> [notice] Update completed: block_post_update_replace_node_type_condition
> [notice] Update started: node_post_update_rebuild_node_revision_routes
> [notice] Update completed: node_post_update_rebuild_node_revision_routes
> [notice] Update started: system_post_update_delete_authorize_settings
> [notice] Update completed: system_post_update_delete_authorize_settings
> [notice] Update started: system_post_update_sort_all_config
> [notice] Update completed: system_post_update_sort_all_config
> [notice] Update started: user_post_update_update_roles
> [notice] The role anonymous user has had the following non-existent permission(s) removed: access site map, see menu_editor placeholder pages, use exclude node title.
> [notice] The role authenticated user has had the following non-existent permission(s) removed: access site map, use exclude node title.
> [notice] The roles anonymous user, authenticated user have had non-existent permissions removed. Check the logs for details.
> [notice] Update completed: user_post_update_update_roles
> [notice] Update started: views_post_update_sort_identifier
> [notice] Update completed: views_post_update_sort_identifier
In ProcessBase.php line 171:
Unable to decode output into JSON: Syntax error
{
"0": {
"user": {
"9301": {
"results": {
"query": null,
"success": true
},
"type": "update"
},
"update_roles": {
"results": {
"query": "The roles <em class="placeholder">anonymous user, authenticated user</em> have had non-existent permissions removed. Check the logs for deta
ils.",
"success": true
},
"type": "post_update"
}
},
"block": {
"replace_node_type_condition": {
"results": {
"query": null,
"success": true
},
"type": "post_update"
}
},
"node": {
"rebuild_node_revision_routes": {
"results": {
"query": null,
"success": true
},
"type": "post_update"
}
},
"system": {
"delete_authorize_settings": {
"results": {
"query": null,
"success": true
},
"type": "post_update"
},
"sort_all_config": {
"results": {
"query": null,
"success": true
},
"type": "post_update"
}
},
"views": {
"sort_identifier": {
"results": {
"query": null,
"success": true
},
"type": "post_update"
}
}
},
"drush_batch_process_finished": true
}
The double quotes within the "update_roles":"results":"query" string appear to be what are causing the upset. (The carriage returns in that string were part of the actual output.)
Subsequent "drush updatedb" commands simply state that there are no updates with no errors reported. But attempts to open any page (public or admin) failed.
Since the admin interface was no longer available to check if Drupal caught any errors, I used a Perl/Tk tool of my own design that directly reads the database to report on what is in the watchdog table and other events. That tool showed that Drupal does report an error when I try to open anything page on the site (I replaced the actual site path with {thesitebase}):
'%file' => '{thesitebase}\web\core\lib\Drupal\Core\Plugin\Context\Context.php',
'%function' => 'Drupal\Core\Plugin\Context\Context->getContextValue()',
'%line' => 73,
'%type' => 'Drupal\Component\Plugin\Exception\ContextException',
'@message' => 'The 'entity:user' context is required and not present.',
'@backtrace_string' => '#0 {thesitebase}\web\core\lib\Drupal\Core\ParamConverter\EntityConverter.php(140): Drupal\Core\Plugin\Context\Context->getContextValue()
#1 {thesitebase}\web\core\lib\Drupal\Core\ParamConverter\ParamConverterManager.php(100): Drupal\Core\ParamConverter\EntityConverter->convert('770', Array, 'node', Array)
#2 {thesitebase}\web\core\lib\Drupal\Core\Access\AccessManager.php(90): Drupal\Core\ParamConverter\ParamConverterManager->convert(Array)
#3 {thesitebase}\web\core\lib\Drupal\Core\Menu\DefaultMenuLinkTreeManipulators.php(210): Drupal\Core\Access\AccessManager->checkNamedRoute('entity.node.can...', Array, Object(Drupal\Core\Session\AccountProxy), true)
#4 {thesitebase}\web\core\lib\Drupal\Core\Menu\DefaultMenuLinkTreeManipulators.php(92): Drupal\Core\Menu\DefaultMenuLinkTreeManipulators->menuLinkCheckAccess(Object(Drupal\menu_link_content\Plugin\Menu\MenuLinkContent))
#5 [internal function]: Drupal\Core\Menu\DefaultMenuLinkTreeManipulators->checkAccess(Array)
#6 {thesitebase}\web\core\lib\Drupal\Core\Menu\MenuLinkTree.php(149): call_user_func(Array, Array)
#7 {thesitebase}\web\core\modules\system\src\Plugin\Block\SystemMenuBlock.php(193): Drupal\Core\Menu\MenuLinkTree->transform(Array, Array)
#8 {thesitebase}\web\core\modules\block\src\BlockViewBuilder.php(171): Drupal\system\Plugin\Block\SystemMenuBlock->build()
#9 [internal function]: Drupal\block\BlockViewBuilder::preRender(Array)
#10 {thesitebase}\web\core\lib\Drupal\Core\Security\DoTrustedCallbackTrait.php(101): call_user_func_array(Array, Array)
#11 {thesitebase}\web\core\lib\Drupal\Core\Render\Renderer.php(772): Drupal\Core\Render\Renderer->doTrustedCallback(Array, Array, 'Render #pre_ren...', 'exception', 'Drupal\\Core\\Ren...')
#12 {thesitebase}\web\core\lib\Drupal\Core\Render\Renderer.php(363): Drupal\Core\Render\Renderer->doCallback('#pre_render', Array, Array)
#13 {thesitebase}\web\core\lib\Drupal\Core\Render\Renderer.php(435): Drupal\Core\Render\Renderer->doRender(Array)
#14 {thesitebase}\web\core\lib\Drupal\Core\Render\Renderer.php(201): Drupal\Core\Render\Renderer->doRender(Array, false)
#15 {thesitebase}\web\core\lib\Drupal\Core\Template\TwigExtension.php(463): Drupal\Core\Render\Renderer->render(Array)
#16 {thesitebase}\web\sites\default\files\php\twig\61d746f61cd7b_page.html.twig_-mba0TK8lmguGuiDYYaNh9lp7\oCZvPHaeT84n6YaBbJqRvhCqZ7uVWA_83aBD0zyo_ss.php(72): Drupal\Core\Template\TwigExtension->escapeFilter(Object(Drupal\Core\Template\TwigEnvironment), Array, 'html', NULL, true)
#17 {thesitebase}\vendor\twig\twig\src\Template.php(405): __TwigTemplate_ddbd5026d0d4341c27e21b762350bfe96e8a92622d09598b9a624eb9d8b36cc4->doDisplay(Array, Array)
#18 {thesitebase}\vendor\twig\twig\src\Template.php(378): Twig\Template->displayWithErrorHandling(Array, Array)
#19 {thesitebase}\vendor\twig\twig\src\Template.php(390): Twig\Template->display(Array)
#20 {thesitebase}\web\core\themes\engines\twig\twig.engine(55): Twig\Template->render(Array)
#21 {thesitebase}\web\core\lib\Drupal\Core\Theme\ThemeManager.php(384): twig_render_template('themes/custom/d...', Array)
#22 {thesitebase}\web\core\lib\Drupal\Core\Render\Renderer.php(422): Drupal\Core\Theme\ThemeManager->render('page', Array)
#23 {thesitebase}\web\core\lib\Drupal\Core\Render\Renderer.php(201): Drupal\Core\Render\Renderer->doRender(Array, false)
#24 {thesitebase}\web\core\lib\Drupal\Core\Template\TwigExtension.php(463): Drupal\Core\Render\Renderer->render(Array)
#25 {thesitebase}\web\sites\default\files\php\twig\61d746f61cd7b_html.html.twig_J17zj6MPfb7Nq7zxjmcGsAbdD\T4hxiOGif2VSQDw6UtWjNm07SKXQyWzwXz7-GzafMN8.php(84): Drupal\Core\Template\TwigExtension->escapeFilter(Object(Drupal\Core\Template\TwigEnvironment), Array, 'html', NULL, true)
#26 {thesitebase}\vendor\twig\twig\src\Template.php(405): __TwigTemplate_cb7e698015803eec233db9f6c379f81a2821ad92cfc4696b76a442ae5b538b1f->doDisplay(Array, Array)
#27 {thesitebase}\vendor\twig\twig\src\Template.php(378): Twig\Template->displayWithErrorHandling(Array, Array)
#28 {thesitebase}\vendor\twig\twig\src\Template.php(390): Twig\Template->display(Array)
#29 {thesitebase}\web\core\themes\engines\twig\twig.engine(55): Twig\Template->render(Array)
#30 {thesitebase}\web\core\lib\Drupal\Core\Theme\ThemeManager.php(384): twig_render_template('themes/custom/d...', Array)
#31 {thesitebase}\web\core\lib\Drupal\Core\Render\Renderer.php(422): Drupal\Core\Theme\ThemeManager->render('html', Array)
#32 {thesitebase}\web\core\lib\Drupal\Core\Render\Renderer.php(201): Drupal\Core\Render\Renderer->doRender(Array, false)
#33 {thesitebase}\web\core\lib\Drupal\Core\Render\MainContent\HtmlRenderer.php(162): Drupal\Core\Render\Renderer->render(Array)
#34 {thesitebase}\web\core\lib\Drupal\Core\Render\Renderer.php(564): Drupal\Core\Render\MainContent\HtmlRenderer->Drupal\Core\Render\MainContent\{closure}()
#35 {thesitebase}\web\core\lib\Drupal\Core\Render\MainContent\HtmlRenderer.php(163): Drupal\Core\Render\Renderer->executeInRenderContext(Object(Drupal\Core\Render\RenderContext), Object(Closure))
#36 {thesitebase}\web\core\lib\Drupal\Core\EventSubscriber\MainContentViewSubscriber.php(90): Drupal\Core\Render\MainContent\HtmlRenderer->renderResponse(Array, Object(Symfony\Component\HttpFoundation\Request), Object(Drupal\Core\Routing\CurrentRouteMatch))
#37 [internal function]: Drupal\Core\EventSubscriber\MainContentViewSubscriber->onViewRenderArray(Object(Symfony\Component\HttpKernel\Event\ViewEvent), 'kernel.view', Object(Drupal\Component\EventDispatcher\ContainerAwareEventDispatcher))
#38 {thesitebase}\web\core\lib\Drupal\Component\EventDispatcher\ContainerAwareEventDispatcher.php(142): call_user_func(Array, Object(Symfony\Component\HttpKernel\Event\ViewEvent), 'kernel.view', Object(Drupal\Component\EventDispatcher\ContainerAwareEventDispatcher))
#39 {thesitebase}\vendor\symfony\http-kernel\HttpKernel.php(163): Drupal\Component\EventDispatcher\ContainerAwareEventDispatcher->dispatch(Object(Symfony\Component\HttpKernel\Event\ViewEvent), 'kernel.view')
#40 {thesitebase}\vendor\symfony\http-kernel\HttpKernel.php(80): Symfony\Component\HttpKernel\HttpKernel->handleRaw(Object(Symfony\Component\HttpFoundation\Request), 1)
#41 {thesitebase}\web\core\lib\Drupal\Core\StackMiddleware\Session.php(58): Symfony\Component\HttpKernel\HttpKernel->handle(Object(Symfony\Component\HttpFoundation\Request), 1, true)
#42 {thesitebase}\web\core\lib\Drupal\Core\StackMiddleware\KernelPreHandle.php(48): Drupal\Core\StackMiddleware\Session->handle(Object(Symfony\Component\HttpFoundation\Request), 1, true)
#43 {thesitebase}\web\core\modules\page_cache\src\StackMiddleware\PageCache.php(191): Drupal\Core\StackMiddleware\KernelPreHandle->handle(Object(Symfony\Component\HttpFoundation\Request), 1, true)
#44 {thesitebase}\web\core\modules\page_cache\src\StackMiddleware\PageCache.php(128): Drupal\page_cache\StackMiddleware\PageCache->fetch(Object(Symfony\Component\HttpFoundation\Request), 1, true)
#45 {thesitebase}\web\core\modules\page_cache\src\StackMiddleware\PageCache.php(82): Drupal\page_cache\StackMiddleware\PageCache->lookup(Object(Symfony\Component\HttpFoundation\Request), 1, true)
#46 {thesitebase}\web\core\lib\Drupal\Core\StackMiddleware\ReverseProxyMiddleware.php(48): Drupal\page_cache\StackMiddleware\PageCache->handle(Object(Symfony\Component\HttpFoundation\Request), 1, true)
#47 {thesitebase}\web\core\lib\Drupal\Core\StackMiddleware\NegotiationMiddleware.php(51): Drupal\Core\StackMiddleware\ReverseProxyMiddleware->handle(Object(Symfony\Component\HttpFoundation\Request), 1, true)
#48 {thesitebase}\vendor\stack\builder\src\Stack\StackedHttpKernel.php(23): Drupal\Core\StackMiddleware\NegotiationMiddleware->handle(Object(Symfony\Component\HttpFoundation\Request), 1, true)
#49 {thesitebase}\web\core\lib\Drupal\Core\DrupalKernel.php(708): Stack\StackedHttpKernel->handle(Object(Symfony\Component\HttpFoundation\Request), 1, true)
#50 {thesitebase}\web\index.php(19): Drupal\Core\DrupalKernel->handle(Object(Symfony\Component\HttpFoundation\Request))
#51 {main}',
So, as it stands, we cannot take Drupal 9.3 until this gets fixed.