fix: #3622092 Install canvas_page_template_component from the recipe so Canvas does not install it during RecipeAppliedEvent
Problem
On a plain drupal/cms codebase (Drupal core 11.4.6, drupal/canvas 1.11.0, no patches of any kind), installing the Horizon Aid site template fails:
drush site:install recipes/horizonaidexits 1 with a RuntimeException: You have requested a synthetic service (kernel), thrown while the RecipeAppliedEvent is being dispatched.
Root cause
Drupal\canvas\EventSubscriber\RecipeSubscriber reaches PageVariantMigration::createFromPageRegions(), which installs the canvas_page_template_component module when a theme that has page regions has no page variant yet. Installing a module during that dispatch rebuilds the service container underneath the listeners that have not run yet. Drupal CMS's own drupal_cms_helper RecipeSubscriber then resolves an OOP hook class through a ClassResolver that is still holding the pre-rebuild container, and the install dies with the synthetic-kernel error.
Horizon Aid always meets the trigger condition because it ships canvas.page_region.vartheme_bs5_horizonaid.header and canvas.page_region.vartheme_bs5_horizonaid.footer.
Control test on the identical codebase: Drupal CMS's own byte site template ships no page regions and installs green — which is what isolates the page regions as the trigger.
The change
Ten lines in recipe.yml only: add canvas_page_template_component to the recipe's own install list, with a comment explaining why and @see pointers to the two upstream classes. The module then already exists when the event fires, so nothing is installed mid-dispatch.
Verification (all run locally today, plain drupal/cms, core 11.4.6, canvas 1.11.0, no patches)
drush site:install recipes/horizonaidexits0.- The Drupal CMS installer path works too:
drush site:install drupal_cms_installer installer_site_template_form.add_ons=horizonaidexits0. - The site serves: front page plus
/about,/resources,/programs,/countries,/events,/donate,/impact,/terms-and-conditions,/user/loginand/searchall return HTTP 200. - Search returns results after indexing.
- Content and config present: 70 nodes, 8 Canvas pages, 74 media items, default theme
vartheme_bs5_horizonaid. - Zero PHP errors in watchdog, zero browser console errors.
Note for reviewers
The underlying defect is upstream in drupal/canvas: a module installed during RecipeAppliedEvent strands earlier-resolved listeners on a stale container. This change only stops Horizon Aid triggering it. An upstream Canvas issue is worth filing separately.
AI policy disclosure
AI-Generated: Yes
Assisted by Claude Code (Claude Opus 5). The reproduction, the root cause and the fix were verified by a human-run local install, per the Policy on the use of AI when contributing to Drupal.
Checkpoints:
- File an issue
- Addition/Change/Update/Fix
- Testing to ensure no regression
- Automated unit testing coverage
- Automated functional testing coverage
- UX/UI designer responsibilities
- Readability
- Accessibility
- Performance
- Security
- Developer Documentation
- User Guide Documentation
- Reviewed by human
- Code review by maintainers
- Full testing and approval
- Credit contributors
- Review with the product owner
- Release notes snippet
- Release