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
- Install through the browser installer, picking the Horizon Aid site template. The install completes.
- 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_1canvas.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.
Why not patch Canvas instead
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
activein the header page region and the Country full content template, so Canvas pages render on a Drupal CMS base instead of throwingOutOfRangeExceptionon a stale hash.
AI-Generated: Yes
Issue fork horizonaid-3620437
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
Comment #4
rajab natshahMeasured 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
088941eondrupal/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 pins4171719f53c41b9d, the installed component's active version is9b679273be9319adsdc.vartheme_bs5_horizonaid.icon-toggle- header pinsc42c2d3c773c4f6c, active is9b1120a77a9891d1Canvas 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 tosdc.*as well. The difference is the failure mode, not the portability: a stalesdc.*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 staleblock.*pin throwsOutOfRangeExceptionand 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
088941eon a plain Drupal CMS base produced two different site-wide 500s: one the CanvasOutOfRangeExceptiondescribed here, and one aPluginNotFoundExceptionfor theredirectandultimate_cron_jobentity 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
/,/countries,/programs,/events,/resources,/about,/donate,/user/login,/admin/contentOutOfRangeExceptionThe footer file already uses
activefor 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
activeis being prepared, so a code change is coming rather than only this comment.AI-Generated: Yes
Comment #6
rajab natshahComment #8
rajab natshah✅ Released horizonaid-1.0.0-alpha2