Problem/Motivation

When a site uses a custom theme generated from the vartheme_bs5 starterkit
(via php core/scripts/drupal generate-theme), setting that custom theme
as the default breaks every page that uses Canvas components. The errors appear immediately
on front-end pages and in the Drupal watchdog log:

  OutOfRangeException: The requested version `16049086a06ff817` is not available.
  Available versions: `c0b39338e25589bb`.                                                                                                                                                                                         
  

This happens because Canvas stores component IDs (e.g. sdc.vartheme_bs5.card-featured) and their versioned property snapshots in multiple places:

  • Config entities — canvas.content_template.*, core.entity_view_display.*
  • SQL field tables — canvas_page__components, canvas_page_revision__components
  • Body/text fields — HTML content containing hardcoded theme filesystem paths

None of these are updated when the active theme is changed through the Drupal admin UI or via Drush.

Proposed resolution

Extend the existing ActiveThemeChangeSubscriber in varbase_components
to automatically perform a full migration whenever the default theme changes between two themes
that both have auto_switch_components: true in their .info.yml.

The subscriber now runs four operations in sequence on ConfigEvents::SAVE for system.theme:

  1. Config entity migration — Replaces all SDC component ID prefixes
    (sdc.oldtheme.sdc.newtheme.), theme dependency references,
    and filesystem paths (themes/contrib/oldtheme/themes/custom/newtheme/)
    across every config object, using regex patterns safe enough not to corrupt unrelated configs.
    Canvas component definition configs for the old theme (canvas.component.sdc.oldtheme.*)
    are intentionally skipped to avoid UUID conflicts on cache rebuild.
  2. Content entity field migration — Discovers all content entity types that have
    component_tree fields, resolves their SQL table mapping, and updates the
    components_component_id column in both the data and revision tables using
    Drupal's database abstraction API ($database->update()).
  3. Text field path replacement — Scans all text/body fields across all content
    entities for hardcoded theme filesystem paths and replaces them in-place using a SQL
    REPLACE() expression, avoiding reliance on a specific primary-key column name.
  4. Component version hash repair — After component IDs are updated, stored
    component_version hashes may reference snapshots that only exist in the old
    theme's canvas component configs. This step recursively walks every config's raw data,
    finds any component_version paired with a new-theme component ID whose stored
    version is no longer valid, and replaces it with the current active version loaded from the
    canvas component entity.

Drush Commands Added

Three new Drush commands are provided for manual runs, diagnostics, and post-upgrade repairs:

  • drush varbase-components:switch-theme old_theme new_theme
    (vc-switch) — Runs the full four-step migration pipeline manually.
    Supports --dry-run to preview changes without saving.
  • drush varbase-components:fix-versions theme
    (vc-fix-versions) — Re-runs only the version hash repair for a given theme.
    Useful after importing config from a different environment.
  • drush varbase-components:scan-refs theme
    (vc-scan) — Scans all configs and entity field tables for references to the
    given theme name and prints a structured report. Expected references (the old theme's own
    component definitions) are annotated as such.

Remaining Considerations

  • The subscriber fires during ConfigEvents::SAVE which means it runs
    synchronously inside the theme-change request. On sites with many canvas pages
    or content templates this could add latency; a follow-up could optionally queue
    the migration as a batch operation.
  • Only themes with auto_switch_components: true in their .info.yml
    trigger the migration. Switching to or from a theme that does not have this flag is a
    no-op, preserving backward compatibility.
  • Canvas component definition configs for the old theme
    (canvas.component.sdc.oldtheme.*) are left intact. They belong to the
    old theme and removing or renaming them would break any remaining references from that
    theme's own templates.

Remaining tasks

  • ✅ File an issue about this project
  • ✅ Addition/Change/Update/Fix to this project
  • ✅ Testing to ensure no regression
  • ✅ Automated unit/functional testing coverage
  • ✅ Developer Documentation support on feature change/addition
  • ➖ User Guide Documentation support on feature change/addition
  • ➖ UX/UI designer responsibilities
  • ➖ Accessibility and Readability
  • ✅ Code review from 1 Varbase core team member
  • ✅ Full testing and approval
  • ✅ Credit contributors
  • ✅ Review with the product owner
  • ✅ Update Release Notes and Update Helper on new feature change/addition
  • ❌ Release varbase-11.0.0-alpha1, varbase_starter-1.0.0-alpha1, varbase_components-4.0.0-alpha1

Varbase update type

  • ✅ No Update
  • ➖ Optional Update
  • ➖ Forced Update
  • ➖ Forced Update if Unchanged

User interface changes

  • N/A

API changes

  • N/A

Data model changes

  • N/A

Release notes snippet

  • feat: #3584333 Auto-switch Canvas component IDs, content templates, and entity field data when changing the default theme

Comments

rajab natshah created an issue. See original summary.

  • rajab natshah committed 2f155853 on 4.0.x
    feat: #3584333 Auto-switch Canvas component IDs, content templates, and...
rajab natshah’s picture

Assigned: rajab natshah » josebc
Issue summary: View changes
Status: Active » Needs review
rajab natshah’s picture

Assigned: josebc » Unassigned
Status: Needs review » Fixed

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.

rajab natshah’s picture

Issue summary: View changes

  • rajab natshah committed e95e5024 on 4.0.x
    feat: #3584333 Auto-switch Canvas component IDs, content templates, and...
rajab natshah’s picture

rajab natshah’s picture

Issue summary: View changes

Status: Fixed » Closed (fixed)

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