Active
Project:
Drupal CMS development repository
Component:
General
Priority:
Normal
Category:
Bug report
Assigned:
Unassigned
Issue tags:
Reporter:
Created:
2 Apr 2026 at 06:31 UTC
Updated:
8 Apr 2026 at 09:21 UTC
Jump to comment: Most recent


Comments
Comment #2
pameeela commentedComment #3
pameeela commentedComment #4
penyaskitoAssets and Brandkits are config entities, so they need to be explicitly installed, and are required by Canvas.
Maybe Haven's recipe should define:
For installing the config entities.
Or as a minimal:
for avoiding the code component editor problem.
But you would still miss
which can cause other issues.
So I think it's unavoidable to define:
Comment #5
pameeela commented@penyaskito do you know when
canvas.brand_kit.global.ymlgot added? I suspect it was after this was converted into a monolith so it's not included in the recipe's config (all of the other config you mentioned is included).I have wondered about this specific issue where a module's config changes, the site template has no way of knowing this. I think the only way to prevent it is to do what you've suggested with:
But this is at odds with the monolithic approach. Going to repurpose the issue to be about that more broadly.
Comment #6
pameeela commentedComment #7
penyaskitoIt got added in 1.3.0 (#3577631). We provide hook_install() and a post_upgrade.
The real problem seems to be that
drupal_cms_site_template_baseshould includeAs I assume all the monoliths started from that and used
site:export, they all missed those config entities.And if they were generated with a version < 1.3.0, they are skipping the install path.
I think that's a problem of the recipes system, not canvas itself. It's raised in canvas because of the peculiar case of requiring config entities to be installed, but can be triggered in many ways. e.g.
1. Module X 1.0.0 (or even core) provides config schema for block settings.
2. A recipe was built with X 1.0.0 and provides a block with that schema.
3. When installing the recipe, block with schema for X 1.0.0 is installed, but the code for X 1.2.0 is downloaded.
4. Any update_N hooks or post_updates WON'T run, so your block is never updated to the new schema.
The workaround is that recipes/site template devs need to be up-to-date. The problem is that this might be too much of a maintenance burden.
Comment #8
phenaproximaI have fielded several requests to make it easier to condense monolithic site templates, so that they can bring in third-party bits without deviating from them. So I think now's the time to make it happen.
Rather than having
site:exporttry to be "smart", I'd rather put another tool into creators' hands, which allows them to try merging a recipe into another recipe. Something like this:If the config shipped by
some_recipematches the subset that's inmy_site_template,some_recipegets merged intomy_site_templateas a dependency, and the duplicated config is removed.If there are changes detected, the command exits, unless you pass a
--forceoption, in which case the command will proceed anyhow.We could make this even more convenient to use by adding a
--mergeoption tosite:export:Comment #9
penyaskito@phenaproxima That's great, but won't solve the main problem described here. The problem in the IS and described in #7 is not affecting monoliths, but any recipe.
Comment #11
phenaproxima@penyaskito: My proposal in #8 is not meant to be a holistic solution to this problem (I should have clarified that; my bad).
What it is meant to do is make it easier to construct site templates which can stay up-to-date, by offloading the parts that you, as the site template author, don't really want to maintain.
Comment #14
wim leers#7++ — great insight, @penyaskito!
It made me realize something.
Drupal 8+'s config management system is designed for config management of a given site. Config exports make sense for the site they were exported from, because they assume a certain DB schema/(post) update hooks. (Exported config declares dependencies, but only on extensions, not versions.) It's the responsibility of the site builder/developer to know what config can be imported on another environment (module versions — schemas really — must match). Failure to do so may lead to hard-to-debug errors, but at least is isolated and can be rolled back (when following config management best practices).
The Recipe system changes that, drastically. Recipes reuses the config management and "config export" functionality, but it is intended to be able to target any site. Meaning it is impossible for a site builder who applies a recipe to know which module versions were used while building the recipe: A) a different person built it, B) the site in which it was built is not publicly available, C) recipes do not specify such metadata, D) config entities do not declare which module version was installed at export time, D) they definitely do not declare which update paths had been applied.
So this is NOT about "an update path for the recipe" — it's about being able to apply update paths (that have already been applied to the site) to config being installed during recipe application (where that recipe's config entities were created for a prior version of the module that provides those config entities). That requires knowing which update paths have already been applied to each exported config entity.
IOW: I think config exported for recipes needs additional metadata (much like
_core: { default_config_hash: … }) to be able to know which update paths have already been applied.For example, a
block.block.*.ymlin a Recipe should contain:… which then means during Recipe application, the missing post-update path (
block_post_update_set_menu_block_depth_to_null_if_zero) should still be applied, even though on the site that the Recipe is being applied to,block_post_update_set_menu_block_depth_to_null_if_zeroalready ran.Comment #15
wim leersI think the scenario I described in detail in #14 was missed in #3283827: Support multiple config update paths.