{"record":{"id":"c90066f331c65ca2","repo":"framework7io/framework7","slug":"color-name-has-backgrounddefined-but-contrastc","errorCode":null,"errorMessage":"Color ${name} has backgrounddefined, but contrastCurve is not defined.","messagePattern":"Color (.+?) has backgrounddefined, but contrastCurve is not defined\\.","errorType":"validation","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"src/core/shared/material-color-utils.js","lineNumber":442,"sourceCode":"      return void 0 !== toneDeltaPair ? toneDeltaPair(s) : void 0;\n    }\n  });\n}\n\nclass DynamicColor {\n  static fromPalette(args) {\n    return new DynamicColor(args.name ?? \"\", args.palette, args.tone ?? DynamicColor.getInitialToneFromBackground(args.background), args.isBackground ?? !1, args.chromaMultiplier, args.background, args.secondBackground, args.contrastCurve, args.toneDeltaPair);\n  }\n  static getInitialToneFromBackground(background) {\n    return void 0 === background ? s => 50 : s => background(s) ? background(s).getTone(s) : 50;\n  }\n  constructor(name, palette, tone, isBackground, chromaMultiplier, background, secondBackground, contrastCurve, toneDeltaPair) {\n    if (this.name = name, this.palette = palette, this.tone = tone, this.isBackground = isBackground, \n    this.chromaMultiplier = chromaMultiplier, this.background = background, this.secondBackground = secondBackground, \n    this.contrastCurve = contrastCurve, this.toneDeltaPair = toneDeltaPair, this.hctCache = new Map, \n    !background && secondBackground) throw new Error(`Color ${name} has secondBackgrounddefined, but background is not defined.`);\n    if (!background && contrastCurve) throw new Error(`Color ${name} has contrastCurvedefined, but background is not defined.`);\n    if (background && !contrastCurve) throw new Error(`Color ${name} has backgrounddefined, but contrastCurve is not defined.`);\n  }\n  clone() {\n    return DynamicColor.fromPalette({\n      name: this.name,\n      palette: this.palette,\n      tone: this.tone,\n      isBackground: this.isBackground,\n      chromaMultiplier: this.chromaMultiplier,\n      background: this.background,\n      secondBackground: this.secondBackground,\n      contrastCurve: this.contrastCurve,\n      toneDeltaPair: this.toneDeltaPair\n    });\n  }\n  clearCache() {\n    this.hctCache.clear();\n  }\n  getArgb(scheme) {","sourceCodeStart":424,"sourceCodeEnd":460,"githubUrl":"https://github.com/framework7io/framework7/blob/655759126686766530a027b2f8f369c991d63d1c/src/core/shared/material-color-utils.js#L424-L460","documentation":"Conversely, if a DynamicColor defines a background it must also define a contrastCurve, because background-based tone adjustment depends on the contrast curve. Defining background without contrastCurve is incomplete, so the constructor throws (message lacks a space: 'backgrounddefined').","triggerScenarios":"Constructing a DynamicColor with background set but contrastCurve undefined/null.","commonSituations":"Partial copies of existing color definitions where the contrastCurve argument was dropped; shifted constructor arguments leaving contrastCurve null; writing a new color role and forgetting the curve.","solutions":["Add the appropriate ContrastCurve for the color role.","Remove background if the color is not a background role.","Restore the original color definition from upstream material-color-utils."],"exampleFix":"// before\nDynamicColor.fromPalette({ name: 'surface', palette: p, tone: t, background: bg });\n// after\nDynamicColor.fromPalette({ name: 'surface', palette: p, tone: t, background: bg, contrastCurve: ContrastCurve(50, 50, 50, 50) });","handlingStrategy":"validation","validationCode":"function validateBackgroundParams(opts) {\n  if (opts.background && !opts.contrastCurve) {\n    throw new Error(`Color ${opts.name}: background requires contrastCurve`);\n  }\n}","typeGuard":"function isConsistentDynamicColorConfig(opts) {\n  return !(opts.background && !opts.contrastCurve);\n}","tryCatchPattern":"try {\n  const color = DynamicColor.fromPalette(opts);\n} catch (err) {\n  if (/backgrounddefined, but contrastCurve is not defined/.test(err.message)) {\n    throw new Error(`Fix definition of ${opts.name}: add contrastCurve or remove background`);\n  }\n  throw err;\n}","preventionTips":["Require background colors to also declare a ContrastCurve in your color factory.","Copy existing role definitions (e.g. surface) when adding new roles so required fields carry over.","Validate the full color table at startup before theme rendering."],"tags":["material-design","color","dynamic-color","validation"],"backgroundTag":"dynamic-color-invariant-violation","analyzedSha":"655759126686766530a027b2f8f369c991d63d1c","analyzedAt":"2026-09-02T19:48:40.711Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-10T02:17:09.455Z"}