{"record":{"id":"8489a3738d852db3","repo":"framework7io/framework7","slug":"color-name-has-contrastcurvedefined-but-backgr","errorCode":null,"errorMessage":"Color ${name} has contrastCurvedefined, but background is not defined.","messagePattern":"Color (.+?) has contrastCurvedefined, but background is not defined\\.","errorType":"validation","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"src/core/shared/material-color-utils.js","lineNumber":441,"sourceCode":"      const toneDeltaPair = s.specVersion === specVersion ? extendedColor.toneDeltaPair : originlColor.toneDeltaPair;\n      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  }","sourceCodeStart":423,"sourceCodeEnd":459,"githubUrl":"https://github.com/framework7io/framework7/blob/655759126686766530a027b2f8f369c991d63d1c/src/core/shared/material-color-utils.js#L423-L459","documentation":"DynamicColor requires a background function to evaluate contrastCurve: the curve maps contrast ratios to tones only when a background exists. A contrastCurve without background is contradictory, so the constructor throws (note the missing space in 'contrastCurvedefined').","triggerScenarios":"Constructing a DynamicColor with a contrastCurve argument/property while background is undefined/null.","commonSituations":"Positional constructor arguments shifted (chromaMultiplier or secondBackground omitted/null, pushing values into the wrong slots); building colors from config where background was never supplied; typo'd background key.","solutions":["Provide a background function alongside contrastCurve.","Remove contrastCurve if no background contrast behavior is needed.","Fix argument ordering/omissions in the DynamicColor constructor or fromPalette call."],"exampleFix":"// before\nDynamicColor.fromPalette({ name: 'x', palette: p, tone: t, contrastCurve: c });\n// after\nDynamicColor.fromPalette({ name: 'x', palette: p, tone: t, background: bg, contrastCurve: c });","handlingStrategy":"validation","validationCode":"function validateContrastCurveParams(opts) {\n  if (opts.contrastCurve && !opts.background) {\n    throw new Error(`Color ${opts.name}: contrastCurve requires background`);\n  }\n}","typeGuard":"function isConsistentDynamicColorConfig(opts) {\n  return !(opts.contrastCurve && !opts.background);\n}","tryCatchPattern":"try {\n  const color = DynamicColor.fromPalette(opts);\n} catch (err) {\n  if (/contrastCurvedefined/.test(err.message)) {\n    throw new Error(`Fix definition of ${opts.name}: contrastCurve needs a background function`);\n  }\n  throw err;\n}","preventionTips":["Pair contrastCurve and background in a single helper factory so one cannot be omitted.","Avoid long positional constructor calls; use fromPalette with named properties.","Unit-test every color definition at construction time, not lazily at render."],"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"}