Theme SDC instances cause fatal error after theme uninstallation due to core bug: keep in-use Components and switch them to the Fallback ComponentSource
>>> [!note] Migrated issue <!-- Drupal.org comment --> <!-- Migrated from issue #3546188. --> Reported by: [mherchel](https://www.drupal.org/user/118428) Related to !148 >>> <h3 id="overview">Steps to reproduce</h3> <ol> <li>Install <a href="https://github.com/phenaproxima/xb-demo">https://github.com/phenaproxima/xb-demo</a></li> <li>Go to appearance, change default theme to Olivero</li> <li>Uninstall the "Starshot Demo" and "CivicTheme" themes</li> <li>Go to homepage and see errors</li> </ol> <h3>Errors</h3> <pre>The website encountered an unexpected error. Try again later.<br><br>AssertionError: assert($component instanceof Component) in assert() (line 440 of modules/contrib/canvas/src/Plugin/Field/FieldType/ComponentTreeItemList.php).<br>Drupal\canvas\Plugin\Field\FieldType\ComponentTreeItemList-&gt;getHydratedValue() (Line: 354)<br>Drupal\canvas\Plugin\Field\FieldType\ComponentTreeItemList-&gt;getHydratedTree() (Line: 191)<br>Drupal\canvas\Plugin\Field\FieldType\ComponentTreeItemList-&gt;toRenderable() (Line: 28)<br>Drupal\canvas\Plugin\Field\FieldFormatter\NaiveComponentTreeFormatter-&gt;viewElements() (Line: 91)<br>Drupal\Core\Field\FormatterBase-&gt;view() (Line: 275)<br>Drupal\Core\Entity\Entity\EntityViewDisplay-&gt;buildMultiple() (Line: 288)<br>Drupal\layout_builder\Entity\LayoutBuilderEntityViewDisplay-&gt;buildMultiple() (Line: 341)<br>Drupal\Core\Entity\EntityViewBuilder-&gt;buildComponents() (Line: 283)<br>Drupal\Core\Entity\EntityViewBuilder-&gt;buildMultiple() (Line: 240)<br>Drupal\Core\Entity\EntityViewBuilder-&gt;build()<br>call_user_func_array() (Line: 107)<br>Drupal\Core\Render\Renderer-&gt;doTrustedCallback() (Line: 871)<br>Drupal\Core\Render\Renderer-&gt;doCallback() (Line: 433)<br>Drupal\Core\Render\Renderer-&gt;doRender() (Line: 222)<br>Drupal\Core\Render\Renderer-&gt;render() (Line: 242)<br>Drupal\Core\Render\MainContent\HtmlRenderer-&gt;Drupal\Core\Render\MainContent\{closure}() (Line: 622)<br>Drupal\Core\Render\Renderer-&gt;executeInRenderContext() (Line: 235)<br>Drupal\Core\Render\MainContent\HtmlRenderer-&gt;prepare() (Line: 131)<br>Drupal\Core\Render\MainContent\HtmlRenderer-&gt;renderResponse() (Line: 90)<br>Drupal\Core\EventSubscriber\MainContentViewSubscriber-&gt;onViewRenderArray() (Line: 246)<br>Symfony\Component\EventDispatcher\EventDispatcher::Symfony\Component\EventDispatcher\{closure}() (Line: 206)<br>Symfony\Component\EventDispatcher\EventDispatcher-&gt;callListeners() (Line: 56)<br>Symfony\Component\EventDispatcher\EventDispatcher-&gt;dispatch() (Line: 188)<br>Symfony\Component\HttpKernel\HttpKernel-&gt;handleRaw() (Line: 76)<br>Symfony\Component\HttpKernel\HttpKernel-&gt;handle() (Line: 53)<br>Drupal\Core\StackMiddleware\Session-&gt;handle() (Line: 48)<br>Drupal\Core\StackMiddleware\KernelPreHandle-&gt;handle() (Line: 28)<br>Drupal\Core\StackMiddleware\ContentLength-&gt;handle() (Line: 32)<br>Drupal\big_pipe\StackMiddleware\ContentLength-&gt;handle() (Line: 116)<br>Drupal\page_cache\StackMiddleware\PageCache-&gt;pass() (Line: 90)<br>Drupal\page_cache\StackMiddleware\PageCache-&gt;handle() (Line: 48)<br>Drupal\Core\StackMiddleware\ReverseProxyMiddleware-&gt;handle() (Line: 51)<br>Drupal\Core\StackMiddleware\NegotiationMiddleware-&gt;handle() (Line: 53)<br>Drupal\Core\StackMiddleware\AjaxPageState-&gt;handle() (Line: 51)<br>Drupal\Core\StackMiddleware\StackedHttpKernel-&gt;handle() (Line: 715)<br>Drupal\Core\DrupalKernel-&gt;handle() (Line: 19)</pre><p>XB editor gives errors (but doesn't die)</p> <p><img src="https://www.drupal.org/files/issues/2025-09-11/Cursor_and_Drupal_Canvas.png" alt></p> <h3 id="proposed-resolution">Proposed resolution</h3> <p>I know that there's a valid reason this is failing (the components don't exist anymore), but this is a use case that people will run into and there is no way to recover unless you know Drupal well enough to go back to /admin</p> <p>A realistic scenario is the following:</p> <ol> <li>User downloads Drupal CMS</li> <li>Drupal CMS comes with prebuilt homepage in Canvas with components from Mercury</li> <li>User wants to change themes. Installs new theme</li> <li>Uninstalls old theme. </li> <li>Site dead. No way for non-technical user to recover.</li> <li>User is frustrated and throws their monitor across the room</li> <li>User picks up monitor, and goes to wordpress.com</li> <li>User gets coffee and breakfast and then creates a WP website while having a negative experience of Drupal. </li> <li>User tells all their friends over a game of golf.</li> <li>One friend is the CEO of Megacorp Inc, which was evaluating Drupal.</li> <li>Megacorp CEO decides to go with AEM.</li> <li>Drupal is sad.</li> </ol> <p>Handling this like <span class="drupalorg-gitlab-issue-link project-issue-status-info project-issue-status-7"><a href="https://www.drupal.org/project/experience_builder/issues/3519168" title="Status: Closed (fixed)">#3519168: Handle components provided by ComponentSources EXPLICITLY disappearing &mdash; enables deleting JS components that are in use</a></span>, not like <span class="drupalorg-gitlab-issue-link drupalorg-gitlab-link-wrapper"><a href="https://git.drupalcode.org/project/canvas/-/work_items/3470422" class="drupalorg-gitlab-link">https://git.drupalcode.org/project/canvas/-/work_items/3470422</a></span>: in-use <code>Component</code>s should switch to the <code>Fallback</code> source, ensuring graceful degradation. The user then has the choice:</p> <ol> <li>either reinstall the theme, this will cause all <code>Component</code>s that were switched to the fallback to start working for real again, as if nothing happened &#129668; </li><li>or allow content authors to find all component instances (using <code>/admin/appearance/component</code>) and replace them with something else.<br> <h3 id="ui-changes">User interface changes</h3> <p>Don't make Drupal sad. Lets make it fail gracefully:</p> <ol> <li>Before uninstallation: <img src="https://www.drupal.org/files/issues/2025-10-03/Screenshot%202025-10-03%20at%201.01.22%20PM.png"> (the red-ish component instance) </li><li>Uninstall the theme providing that SDC. Uninstallation shows nothing different in the UI </li><li>Canvas UI: recovery is now possible: <img src="https://www.drupal.org/files/issues/2025-10-03/Screenshot%202025-10-03%20at%201.02.44%20PM.png"> </li><li>Live site: nothing to see &mdash; if this SDC had slots, then the contents of those slots would've been rendered. <img src="https://www.drupal.org/files/issues/2025-10-03/Screenshot%202025-10-03%20at%201.05.25%20PM.png"> </li></ol> </li></ol> > Related issue: [Issue #3528723](https://www.drupal.org/node/3528723) > Related issue: [Issue #3528499](https://www.drupal.org/node/3528499) > Related issue: [Issue #3550019](https://www.drupal.org/node/3550019) > Related issue: [Issue #3519168](https://www.drupal.org/node/3519168)
issue