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
- Set extendedColor.isBackground to match originalColor.isBackground.
- Copy the original color definition (or use clone/fromPalette with the correct isBackground) when authoring a spec-version extension.
- 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
- Always pass isBackground explicitly (never rely on defaults) when authoring DynamicColors.
- Use clone()/fromPalette from the original color so flags carry over.
- Lint or test that each spec-version extension matches name and isBackground of its original.
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
- Attempting to extend color ${originalColor.name} with color
- `primaryDim` color is undefined prior to 2025 spec.
- `secondaryDim` color is undefined prior to 2025 spec.
- `tertiaryDim` color is undefined prior to 2025 spec.
- Color ${name} has secondBackgrounddefined, but background is
AI-assisted analysis of framework7io/framework7@6557591266 (2026-09-02).
Data as JSON: /api/errors/f3c348d75cb3ecf7.
Report an issue: GitHub.