d2lang/d2 · error

expected "font-color" to be a valid named color ("orange"),

Error message

expected "font-color" to be a valid named color ("orange"), a hex code ("#f0ff3a"), or a gradient ("linear-gradient(red, blue)")

What it means

D2 validates the "font-color" style with color.ValidColor, which accepts named colors (e.g. "orange"), hex codes ("#f0ff3a"), or gradient expressions ("linear-gradient(red, blue)"). Any other string returns this error.

Source

Thrown at d2graph/d2graph.go:426

		if _, ok := d2fonts.D2_FONT_TO_FAMILY[strings.ToLower(value)]; !ok {
			return fmt.Errorf(`"%v" is not a valid font in our system`, value)
		}
		s.Font.Value = strings.ToLower(value)
	case "font-size":
		if s.FontSize == nil {
			break
		}
		f, err := strconv.Atoi(value)
		if err != nil || (f < 8 || f > 100) {
			return errors.New(`expected "font-size" to be a number between 8 and 100`)
		}
		s.FontSize.Value = value
	case "font-color":
		if s.FontColor == nil {
			break
		}
		if !color.ValidColor(value) {
			return errors.New(`expected "font-color" to be a valid named color ("orange"), a hex code ("#f0ff3a"), or a gradient ("linear-gradient(red, blue)")`)
		}
		s.FontColor.Value = value
	case "animated":
		if s.Animated == nil {
			break
		}
		_, err := strconv.ParseBool(value)
		if err != nil {
			return errors.New(`expected "animated" to be true or false`)
		}
		s.Animated.Value = value
	case "bold":
		if s.Bold == nil {
			break
		}
		_, err := strconv.ParseBool(value)
		if err != nil {
			return errors.New(`expected "bold" to be true or false`)

View on GitHub (pinned to 0d69dca6f5)

Solutions

  1. Use a valid hex code like "#f0ff3a" (e.g. `x.font-color: #ff0000`).
  2. Use one of D2's supported named colors (e.g. "orange", "red").
  3. Replace rgb()/rgba() with the equivalent hex value.
  4. Fix gradient syntax to "linear-gradient(color1, color2)".
  5. Call the library's color.ValidColor (or equivalent) on user input before applying the style.

Example fix

// before (D2)
x: my shape
x.font-color: rgb(255, 0, 0)
// after
x: my shape
x.font-color: #ff0000
Defensive patterns

Strategy: validation

Validate before calling

func validFontColor(v string) bool {
	return color.ValidColor(v) // named color, #hex, or linear-gradient(...)
}
// before applying: if !validFontColor(val) { val = "#000000" }

Type guard

func isHexColor(s string) bool {
	if !strings.HasPrefix(s, "#") {
		return false
	}
	_, err := strconv.ParseUint(strings.TrimPrefix(s, "#"), 16, 64)
	return err == nil && (len(s) == 7 || len(s) == 9)
}

Try / catch

if err := obj.SetStyle("font-color", val); err != nil {
	if strings.Contains(err.Error(), `"font-color" to be a valid named color`) {
		// fallback to a valid default
		val = "#000000"
	}
}

Prevention

When it happens

Trigger: Setting style key "font-color" to an invalid color string, e.g. `x.font-color: lightish-blue`, `font-color: #12345` (bad hex), or a malformed gradient.

Common situations: Users invent color names not in the accepted palette, use CSS rgb()/rgba() functions or 3-digit hex shorthand that the validator rejects, or typo hex codes.

Related errors


AI-assisted analysis of d2lang/d2@0d69dca6f5 (2026-08-31). Data as JSON: /api/errors/ca774c091d7ef6cd. Report an issue: GitHub.