framework7io/framework7 · error · Error

Attempting to extend color ${originalColor.name} as a ${orig

Error message

Attempting to extend color ${originalColor.name} as a ${originalColor.isBackground ? "background" : "foreground"} with color ${extendedColor.name} as a ${extendedColor.isBackground ? "background" : "foreground"} for spec version ${specVersion}.

What it means

validateExtendedColor also asserts that the extended color's isBackground flag matches the original color's. Extending a foreground color with a background variant (or vice versa) for a spec version would produce roles with wrong background/foreground semantics, so the library throws.

Source

Thrown at src/core/shared/material-color-utils.js:397

  static darkerUnsafe(tone, ratio) {
    const darkerSafe = Contrast.darker(tone, ratio);
    return darkerSafe < 0 ? 0 : darkerSafe;
  }
}

class DislikeAnalyzer {
  static isDisliked(hct) {
    const huePasses = Math.round(hct.hue) >= 90 && Math.round(hct.hue) <= 111, chromaPasses = Math.round(hct.chroma) > 16, tonePasses = Math.round(hct.tone) < 65;
    return huePasses && chromaPasses && tonePasses;
  }
  static fixIfDisliked(hct) {
    return DislikeAnalyzer.isDisliked(hct) ? Hct.from(hct.hue, hct.chroma, 70) : hct;
  }
}

function validateExtendedColor(originalColor, specVersion, extendedColor) {
  if (originalColor.name !== extendedColor.name) throw new Error(`Attempting to extend color ${originalColor.name} with color ${extendedColor.name} of different name for spec version ${specVersion}.`);
  if (originalColor.isBackground !== extendedColor.isBackground) throw new Error(`Attempting to extend color ${originalColor.name} as a ${originalColor.isBackground ? "background" : "foreground"} with color ${extendedColor.name} as a ${extendedColor.isBackground ? "background" : "foreground"} for spec version ${specVersion}.`);
}

function extendSpecVersion(originlColor, specVersion, extendedColor) {
  return validateExtendedColor(originlColor, specVersion, extendedColor), DynamicColor.fromPalette({
    name: originlColor.name,
    palette: s => s.specVersion === specVersion ? extendedColor.palette(s) : originlColor.palette(s),
    tone: s => s.specVersion === specVersion ? extendedColor.tone(s) : originlColor.tone(s),
    isBackground: originlColor.isBackground,
    chromaMultiplier: s => {
      const chromaMultiplier = s.specVersion === specVersion ? extendedColor.chromaMultiplier : originlColor.chromaMultiplier;
      return void 0 !== chromaMultiplier ? chromaMultiplier(s) : 1;
    },
    background: s => {
      const background = s.specVersion === specVersion ? extendedColor.background : originlColor.background;
      return void 0 !== background ? background(s) : void 0;
    },
    secondBackground: s => {
      const secondBackground = s.specVersion === specVersion ? extendedColor.secondBackground : originlColor.secondBackground;

View on GitHub (pinned to 6557591266)

Solutions

  1. Set extendedColor.isBackground to match originalColor.isBackground.
  2. Copy the original color definition (or use clone/fromPalette with the correct isBackground) when authoring a spec-version extension.
  3. Restore the spec-version color tables from upstream material-color-utils.

Example fix

// before
DynamicColor.fromPalette({ name: 'surface', palette: p, isBackground: false });
// after
DynamicColor.fromPalette({ name: 'surface', palette: p, isBackground: true });
Defensive patterns

Strategy: validation

Validate before calling

function validateBackgroundFlags(originalColor, extendedColor, specVersion) {
  if (originalColor.isBackground !== extendedColor.isBackground) {
    throw new Error(`spec ${specVersion}: isBackground mismatch for ${originalColor.name}`);
  }
}

Type guard

function backgroundFlagsMatch(original, extended) {
  return original.isBackground === extended.isBackground;
}

Try / catch

try {
  extendSpecVersion(color, specVersion, ext);
} catch (err) {
  if (/as a (background|foreground) with color .* for spec version/.test(err.message)) {
    ext = { ...ext, isBackground: color.isBackground };
  } else throw err;
}

Prevention

When it happens

Trigger: extendSpecVersion called where originalColor.isBackground !== extendedColor.isBackground for the given specVersion.

Common situations: Copying a DynamicColor definition as the spec-version extension but leaving the default isBackground value (false) when the original is a background; swapping color entries in the spec table; hand-writing a 2021/2025 spec variant of a background role.

Related errors


AI-assisted analysis of framework7io/framework7@6557591266 (2026-09-02). Data as JSON: /api/errors/f3c348d75cb3ecf7. Report an issue: GitHub.