d2lang/d2 · error

cannot parse hex color %v

Error message

cannot parse hex color %v

What it means

Hex2RGB parses a hex color string into an RGB struct. It requires a '#' prefix and, for strings longer than 3 chars, strips it; if the string does not start with '#' (or is too short to be a valid hex literal), it returns this error instead of attempting ParseUint.

Source

Thrown at lib/color/color.go:180

// https://github.com/go-playground/colors/blob/main/rgb.go#L89
func (c *RGB) IsLight() bool {
	r := float64(c.Red)
	g := float64(c.Green)
	b := float64(c.Blue)

	hsp := math.Sqrt(0.299*math.Pow(r, 2) + 0.587*math.Pow(g, 2) + 0.114*math.Pow(b, 2))

	return hsp > 130
}

// https://gist.github.com/CraigChilds94/6514edbc6a2db5e434a245487c525c75
func Hex2RGB(hex string) (RGB, error) {
	var rgb RGB
	if len(hex) > 3 && hex[0] == '#' {
		hex = hex[1:]
	} else {
		return RGB{}, fmt.Errorf("cannot parse hex color %v", hex)
	}
	values, err := strconv.ParseUint(hex, 16, 32)
	if err != nil {
		return RGB{}, err
	}

	rgb = RGB{
		Red:   uint8(values >> 16),
		Green: uint8((values >> 8) & 0xFF),
		Blue:  uint8(values & 0xFF),
	}

	return rgb, nil
}

// https://www.w3.org/TR/css-color-4/#svg-color
var namedRgbMap = map[string][]uint8{
	"aliceblue":            {240, 248, 255}, // #F0F8FF

View on GitHub (pinned to 0d69dca6f5)

Solutions

  1. Prefix the string with '#' before calling Hex2RGB
  2. Validate with a regexp like ^#[0-9a-fA-F]{3,8}$ before calling
  3. Normalize user/config color input to canonical '#RRGGBB' form
  4. If the '#' was stripped upstream, keep the original form for parsing

Example fix

// before
rgb, err := color.Hex2RGB("4A6FA5")
// after
if !strings.HasPrefix(hex, "#") { hex = "#" + hex }
rgb, err := color.Hex2RGB(hex)
Defensive patterns

Strategy: validation

Validate before calling

var hexRe = regexp.MustCompile(`^#[0-9a-fA-F]{3,8}$`)
if !hexRe.MatchString(hex) {
    return fmt.Errorf("not a # hex color: %q", hex)
}

Type guard

func isHexColor(s string) bool {
    return len(s) > 3 && s[0] == '#' && regexp.MustCompile(`^#[0-9a-fA-F]{3,8}$`).MatchString(s)
}

Try / catch

rgb, err := color.Hex2RGB(hex)
if err != nil {
    log.Printf("bad hex color %q: %v", hex, err)
    return fallbackColor
}

Prevention

When it happens

Trigger: Calling Hex2RGB with "4A6FA5", "fff", "#", or any string not beginning with '#' and longer than 3 characters.

Common situations: Colors obtained from config/user input without normalization, or strings already stripped of '#' by earlier processing.

Related errors


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