d2lang/d2 · error

expected "stroke" to be a valid named color ("orange"), a he

Error message

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

What it means

The 'stroke' style key must be a valid color as recognized by color.ValidColor: a named color, a hex code, or a gradient expression. This error is returned when the stroke value fails that check. Note the check is skipped when s.Stroke is nil (key not present).

Source

Thrown at d2graph/d2graph.go:331

}

func (s *Style) Apply(key, value string) error {
	switch key {
	case "opacity":
		if s.Opacity == nil {
			break
		}
		f, err := strconv.ParseFloat(value, 64)
		if err != nil || math.IsNaN(f) || math.IsInf(f, 0) || f < 0 || f > 1 {
			return errors.New(`expected "opacity" to be a number between 0.0 and 1.0`)
		}
		s.Opacity.Value = value
	case "stroke":
		if s.Stroke == nil {
			break
		}
		if !color.ValidColor(value) {
			return errors.New(`expected "stroke" to be a valid named color ("orange"), a hex code ("#f0ff3a"), or a gradient ("linear-gradient(red, blue)")`)
		}
		s.Stroke.Value = value
	case "fill":
		if s.Fill == nil {
			break
		}
		if !color.ValidColor(value) {
			return errors.New(`expected "fill" to be a valid named color ("orange"), a hex code ("#f0ff3a"), or a gradient ("linear-gradient(red, blue)")`)
		}
		s.Fill.Value = value
	case "fill-pattern":
		if s.FillPattern == nil {
			break
		}
		if !go2.Contains(d2ast.FillPatterns, strings.ToLower(value)) {
			return fmt.Errorf(`expected "fill-pattern" to be one of: %s`, strings.Join(d2ast.FillPatterns, ", "))
		}
		s.FillPattern.Value = value

View on GitHub (pinned to 0d69dca6f5)

Solutions

  1. Use a supported format: named color ("orange"), hex ("#f0ff3a"), or gradient ("linear-gradient(red, blue)").
  2. Add the '#' prefix to hex codes and verify 3/6 hex digits.
  3. Check the value against color.ValidColor before applying.

Example fix

// before
x.style.stroke: rgb(255, 0, 0)
// after
x.style.stroke: #ff0000
Defensive patterns

Strategy: validation

Validate before calling

if !color.ValidColor(v) {
    return fmt.Errorf("stroke %q is not a named color, hex code, or gradient", v)
}

Type guard

func validStroke(v string) bool { return color.ValidColor(v) }

Try / catch

if err := applyStyle("stroke", value); err != nil {
    if strings.Contains(err.Error(), "stroke") {
        value = "#000000" // fallback
    }
}

Prevention

When it happens

Trigger: Setting style 'stroke' to a value that is not a named color, hex code (#rrggbb), or linear-gradient(...) — e.g. `stroke: rgb(255,0,0)` if unsupported, `stroke: red-ish`, or empty string.

Common situations: D2 authors using CSS color functions or formats the D2 color parser doesn't accept, misspelling a color name, or omitting the '#' in hex codes.

Related errors


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