Skip to content

Color module regenerates a new random file path on every cache clear, causing spurious config changes #7204

Description

@rfay

Summary

Every time a site's cache is fully cleared, the Color module regenerates a brand new random directory name for a theme's derived CSS files — even when the color palette hasn't changed at all. This gets written into the theme's config ([theme].settings), so a plain cache clear produces a config change with no real content difference.

What happens without a fix (failure mode)

Take any theme with Color module support and a custom color scheme set (for example Basis or Bartik). Every time all caches are cleared — by running drush cache-clear all, bee cc all, clicking "Clear all caches" in the admin UI, or any code path that calls a full cache flush (including some automated ones, like after a config import) — Backdrop rewrites that theme's settings config with new, different-looking file paths such as:

"public://color/basis-726132a6/base.css"

becomes

"public://color/basis-faea8157/base.css"

The actual CSS content is identical; only the random directory name changed. If a site uses Backdrop's Configuration Management to track config in git, this shows up as an unwanted diff in config/active/*.settings.json after every single cache clear, on every environment including production. In practice this means:

  • Config exports/diffs are never "clean" on a color-enabled site — something always looks changed even when nothing was.
  • It's easy to mistake this noise for a real, meaningful configuration change during a deploy or code review.
  • Old generated CSS directories under public://color/ are deleted and re-created every time, for no reason.

Root cause

In color_save_configuration() (core/modules/color/color.module):

$id = $theme_name . '-' . substr(hash('sha256', serialize($palette) . microtime()), 0, 8);

Because microtime() is included in the hash, $id is different on every call, even for the exact same $palette. This function is called from color_rebuild_settings(), which is invoked by color_flush_caches() — Color's implementation of hook_flush_caches() — so it runs on every full cache clear, not just when a color scheme is actually changed.

Steps to reproduce

  1. Enable a theme with Color module support (e.g. Basis) and set/save a custom color palette on its theme settings page.
  2. Note the color.stylesheets / color.files paths in [theme].settings config.
  3. Run a full cache clear (drush cache-clear all or equivalent).
  4. Observe the paths changed to a new random directory, even though the palette is unchanged.
  5. Repeat step 3 — it changes again every time.

Proposed fix

A pull request is attached that makes the $id deterministic (based only on the theme name and palette, dropping microtime()), so an unchanged palette reuses the same directory and no longer produces a config diff. Real palette or theme CSS changes still get a new directory as before. Browser cache-busting after a real cache clear is unaffected, since Backdrop already appends a separate, global cache-busting query string to all CSS/JS requests on every cache clear (_backdrop_flush_css_js()), independent of this file path.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions