`PageRegion::createFromBlockLayout()` fatals with an `assert()` failure for any block carrying a `context_mapping` setting (e.g. Views blocks with a contextual filter)
## Problem Saving the core "Appearance > Settings" (`system_theme_settings`) form for a theme that already has Drupal Canvas enabled (i.e. any `canvas.page_region.<theme>.*` config entity already exists) throws an uncaught `AssertionError` and returns a fatal error page, for example when simply uploading a new theme logo: ``` AssertionError: assert([] === iterator_to_array($page_region->getTypedData()->validate())) in assert() (line 348 of modules/contrib/canvas/src/Entity/PageRegion.php) Drupal\canvas\Entity\PageRegion::createFromBlockLayout() (Line: 75) Drupal\canvas\Hook\PageRegionHooks::formSystemThemeSettingsSubmit() (Line: 108) ... ``` Because the "Use Drupal Canvas for page templates" checkbox defaults to checked once any `PageRegion` exists for the theme, this fires on **every** save of the theme settings form, not just when a site builder is intentionally reconfiguring Canvas regions — including routine actions like changing the logo or favicon. ## Root cause `PageRegionHooks::formSystemThemeSettingsSubmit()` calls `PageRegion::createFromBlockLayout($theme)` unconditionally whenever the "Use Drupal Canvas" checkbox is checked, in order to rebuild every theme region from the site's current classic block layout. For each block, it builds the component's `inputs` from the block's raw `settings`, stripping only two known keys: ```php // \Drupal\canvas\Entity\PageRegion::createFromBlockLayout() 'inputs' => \array_diff_key($block->get('settings'), \array_flip([ // Remove these as they can be calculated and hence need not be // stored. 'id', 'provider', ])), ``` However, `context_mapping` is also a standard key that Drupal core writes onto **any** block's `settings` once it is saved through the Block Layout UI, as soon as the block plugin implements `ContextAwarePluginInterface` and declares at least one context definition — every `BlockBase` subclass implements this interface, and `BlockBase::blockForm()`/`blockSubmit()` capture the assignment unconditionally (see `Drupal\Core\Block\BlockBase::blockForm()` / `ContextAwarePluginTrait::setContextMapping()`). This is extremely common for Views blocks whose display has a contextual filter with an entity/numeric validator — even if the mapping ends up empty (`context_mapping: { }`) because nothing was actually mapped, or because the validator has since been changed. Canvas's own component input schema for these components does not recognize `context_mapping` as a supported key, so `$page_region->getTypedData()->validate()` returns a "'context_mapping' is not a supported key" violation, which trips the `assert()` — and because PHP assertions are commonly enabled outside of strict production tuning, this surfaces as an uncaught fatal error rather than a graceful validation message. ## Steps to reproduce 1. Enable Drupal Canvas for a theme with at least one `PageRegion` entity already created. 2. Place a Views block (any view with a block display that has a contextual filter using an "Entity" or "Numeric" argument validator) into any region of that theme, and save it at least once through the Block Layout UI (this is what causes `context_mapping` to be persisted into the block's `settings`, even as an empty array). 3. Go to `admin/appearance/settings/<theme>` and save the form (e.g. by changing the logo). 4. Observe the fatal error / white screen instead of a successful save. ## Proposed resolution Strip `context_mapping` from the block settings the same way `id` and `provider` are already stripped in `PageRegion::createFromBlockLayout()`, since it is calculated block-placement metadata, not a genuine component input: ```php 'inputs' => \array_diff_key($block->get('settings'), \array_flip([ // Remove these as they can be calculated and hence need not be // stored. 'id', 'provider', 'context_mapping', ])), ``` This mirrors the existing rationale in the surrounding comment: `context_mapping` is block-placement plumbing that Canvas's component input schema doesn't (and arguably shouldn't need to) model, and it has no effect on rendering here since affected Views blocks resolve their contextual filter value independently via the view's own `argument_default` plugin when no argument is otherwise provided. A broader fix might also want to more gracefully surface *any* future case of a strippable/unsupported settings key hitting this `assert()` — e.g. downgrading it to a logged validation error with details, rather than an uncaught `AssertionError`, so the failure mode for the next unsupported key is a readable error instead of a blank fatal.
issue