Problem/Motivation

On a plain Drupal CMS base, the install completes and then every Canvas page returns HTTP 500:

OutOfRangeException: The requested version `b168140fdcaebae5` is not available.
Available versions: `7d528e00f56b3abf`.
  in Drupal\canvas\Entity\VersionedConfigEntityBase->assertVersionExists()

config/canvas.page_region.vartheme_bs5_horizonaid.header.yml pins component_version: b168140fdcaebae5 for block.system_branding_block. The component on the installed site carries 7d528e00f56b3abf, so the pin dangles and rendering throws.

Why the pin dangles

Canvas auto-creates a component config entity for each block plugin. On the installed site that entity reports provider: system — Canvas created it, not this recipe. Recipes do not overwrite config that already exists, so the recipe's own config/canvas.component.block.system_branding_block.yml (which declares b168140fdcaebae5) never imports, and the region is left pointing at a version nothing defines.

The hash is derived from the component payload, so which value ends up on disk depends on who created the entity first. That makes a hard-coded hash for an auto-created block component non-portable by construction.

Steps to reproduce

Drupal CMS Project template - Horizon Aid
mkdir -p ~/workmspace/test/my-drupal-site-horizonaid1
cd my-drupal-site-horizonaid1
ddev config --project-type=drupal11 --docroot=web
ddev composer create-project drupal/cms
ddev composer config minimum-stability dev
ddev rm composer.lock
ddev composer require drupal/horizonaid:1.0.x-dev
  1. Install through the browser installer, picking the Horizon Aid site template. The install completes.
  2. Visit /, /about, /programs, /events, /donate — all 500 with the exception above.

Proposed resolution

Use component_version: active for block.* components, which is already this recipe's own convention — canvas.page_region.vartheme_bs5_horizonaid.footer.yml pins active for its block components and renders correctly on both bases.

active is portable because assertVersionExists() accepts a version that either equals active_version or is a key in versioned_properties, and active is always such a key. Canvas resolves it to the local component's current hash at import time — verified by reading the footer region back out of the database after install, where the shipped active values had become concrete per-environment hashes.

Four block.* pins change:

  • canvas.page_region.vartheme_bs5_horizonaid.header.yml — block.system_branding_block, block.system_menu_block.main, block.views_exposed_filter_block.search-block_1
  • canvas.content_template.node.country.full.yml — block.views_block.countries-related_slider

The sdc.* pins are deliberately left alone. Those components ship with vartheme_bs5_horizonaid, so this recipe controls their payload and their hashes are deterministic. Pinning them to a specific version is intentional, and replacing that with active would discard a real guarantee.

vardot/varbase-patches has been carrying canvas MR !927 (#3585221), which makes assertVersionExists() fall back to active_version instead of throwing. That patch is why this bug never showed on Varbase: it silently masked every stale pin. It is being removed (varbase-patches #622), which is what surfaced this.

Fixing the data rather than re-adding the patch keeps to what Drupal CMS and Drupal Canvas provide, with minimal additions and minimal patches.

Remaining tasks

  • ✅ File an issue
  • ✅ Addition/Change/Update/Fix
  • ✅ Testing to ensure no regression
  • ➖ Automated unit/functional testing coverage
  • ➖ Developer Documentation support
  • ➖ User Guide Documentation support
  • ➖ UX/UI designer responsibilities
  • ➖ Accessibility and Readability
  • ❌ Reviewed by a human
  • ❌ Code review by maintainers
  • ❌ Full testing and approval
  • ❌ Credit contributors
  • ❌ Review with the product owner
  • ✅ Update Release Notes
  • ✅ Release, horizonaid-1.0.0-alpha2

User interface changes

  • Canvas pages render on a Drupal CMS base instead of returning 500. No visual change where they already rendered.

API changes

  • N/A

Data model changes

  • Block component references in the header region and the Country full content template resolve to the local component version at import time rather than a fixed hash.

Release notes snippet

  • Pin block component versions to active in the header page region and the Country full content template, so Canvas pages render on a Drupal CMS base instead of throwing OutOfRangeException on a stale hash.

AI-Generated: Yes

Issue fork horizonaid-3620437

Command icon Show commands

Start within a Git clone of the project using the version control instructions.

Or, if you do not have SSH keys set up on git.drupalcode.org:

Comments

rajab natshah created an issue. See original summary.

rajab natshah’s picture

Measured evidence against one part of the Proposed resolution: the sdc.* pins in the header file are stale too, and on a Varbase base rather than a Drupal CMS one.

Fresh install of recipe commit 088941e on drupal/varbase_project:11.0.x-dev (Drupal core 11.4.6, canvas 1.10.1, vartheme_bs5 5.0.0-rc5, varbase 11.0.x-dev), read out of the installed site's active config:

  • sdc.vartheme_bs5_horizonaid.section - header pins 4171719f53c41b9d, the installed component's active version is 9b679273be9319ad
  • sdc.vartheme_bs5_horizonaid.icon-toggle - header pins c42c2d3c773c4f6c, active is 9b1120a77a9891d1

Canvas auto-creates a component config entity for theme SDCs the same way it does for block plugins, so the "whoever creates the entity first wins" mechanism this issue identifies for block.* appears to apply to sdc.* as well. The difference is the failure mode, not the portability: a stale sdc.* pin falls back to the active version silently (Canvas logged 20 "version not found, falling back to active version" warnings on this install), whereas a stale block.* pin throws OutOfRangeException and takes the page down. So the guarantee reads as intact largely because nothing throws.

This failure is per-run, not deterministic

Two fresh installs of the same commit 088941e on a plain Drupal CMS base produced two different site-wide 500s: one the Canvas OutOfRangeException described here, and one a PluginNotFoundException for the redirect and ultimate_cron_job entity types, with the Canvas block pins already resolved. Anyone reproducing this should use a fully fresh build and install each time, because a reused codebase or database lets a previous run's state mask it. That second failure mode is filed separately as #3620718.

Verified with all six header pins set to active

  • Every page 200 anonymous and authenticated: /, /countries, /programs, /events, /resources, /about, /donate, /user/login, /admin/content
  • Zero watchdog errors, zero OutOfRangeException

The footer file already uses active for all 17 of its components, so this would also make the header consistent with the recipe's own convention.

A follow-up MR setting all six header pins to active is being prepared, so a code change is coming rather than only this comment.

AI-Generated: Yes

rajab natshah’s picture

Issue summary: View changes

  • rajab natshah committed 9be57722 on 1.0.x
    fix: #3620437 Pin the header SDC component versions to active
    
rajab natshah’s picture

Issue summary: View changes
Status: Active » Fixed
Issue tags: +horizonaid-1.0.0-alpha2

Now that this issue is closed, review the contribution record.

As a contributor, attribute any organization that helped you, or if you volunteered your own time.

Maintainers, credit people who helped resolve this issue.

Status: Fixed » Closed (fixed)

Automatically closed - issue fixed for 2 weeks with no activity.