wavetermdev/waveterm · error

color must be in #RRGGBB or #RRGGBBAA format

Error message

color must be in #RRGGBB or #RRGGBBAA format

What it means

After stripping the leading '#', validateHexColor requires exactly 6 hex digits (#RRGGBB) or 8 (#RRGGBBAA). Any other length — 3-digit shorthand like #F00, 4-digit #RGBA, or missing digits — fails this check before hex decoding is attempted.

Source

Thrown at cmd/wsh/cmd/wshcmd-setbg.go:72

	setBgCmd.Flags().Float64Var(&setBgOpacity, "opacity", 0.5, "background opacity (0.0-1.0)")
	setBgCmd.Flags().BoolVar(&setBgTile, "tile", false, "tile the background image")
	setBgCmd.Flags().BoolVar(&setBgCenter, "center", false, "center the image without scaling")
	setBgCmd.Flags().StringVar(&setBgSize, "size", "auto", "size for centered images (px, %, or auto)")
	setBgCmd.Flags().BoolVar(&setBgClear, "clear", false, "clear the background")
	setBgCmd.Flags().BoolVar(&setBgPrint, "print", false, "print the metadata without applying it")
	setBgCmd.Flags().StringVar(&setBgBorderColor, "border-color", "", "block frame border color (#RRGGBB, #RRGGBBAA, or CSS color name)")
	setBgCmd.Flags().StringVar(&setBgActiveBorderColor, "active-border-color", "", "block frame focused border color (#RRGGBB, #RRGGBBAA, or CSS color name)")

	setBgCmd.MarkFlagsMutuallyExclusive("tile", "center")
}

func validateHexColor(color string) error {
	if !strings.HasPrefix(color, "#") {
		return fmt.Errorf("color must start with #")
	}
	colorHex := color[1:]
	if len(colorHex) != 6 && len(colorHex) != 8 {
		return fmt.Errorf("color must be in #RRGGBB or #RRGGBBAA format")
	}
	_, err := hex.DecodeString(colorHex)
	if err != nil {
		return fmt.Errorf("invalid hex color: %v", err)
	}
	return nil
}

func validateColor(color string) error {
	if strings.HasPrefix(color, "#") {
		return validateHexColor(color)
	}
	if !CssColorNames[strings.ToLower(color)] {
		return fmt.Errorf("invalid color %q: must be a hex color (#RRGGBB or #RRGGBBAA) or a CSS color name", color)
	}
	return nil
}

View on GitHub (pinned to a4447c1563)

Solutions

  1. Expand 3-digit hex to 6 digits: '#F00' -> '#FF0000'.
  2. For transparency use the 8-digit form '#RRGGBBAA' (or use the --opacity flag instead).
  3. Count the digits: exactly 6 or exactly 8 hex characters after '#'.

Example fix

// before
wsh setbg --border-color '#F00'
// after
wsh setbg --border-color '#FF0000'
Defensive patterns

Strategy: validation

Validate before calling

hexPart := strings.TrimPrefix(color, "#")
if len(hexPart) != 6 && len(hexPart) != 8 {
    return fmt.Errorf("color %q must be #RRGGBB or #RRGGBBAA", color)
}

Type guard

func isFullHexColor(c string) bool {
    if !strings.HasPrefix(c, "#") { return false }
    n := len(c) - 1
    return n == 6 || n == 8
}

Try / catch

if err := validateHexColor(c); err != nil {
    if strings.Contains(err.Error(), "#RRGGBB") { c = expandShorthand(c) } // '#F00' -> '#FF0000'
}

Prevention

When it happens

Trigger: Calling `wsh setbg --border-color '#F00'` (3-digit), `'#RRGGBBAA'` with wrong digit count like '#1234567', or an empty '#'.

Common situations: Using CSS 3-digit shorthand that Wave's setbg doesn't support; pasting truncated hex strings; appending an alpha channel incorrectly.

Related errors


AI-assisted analysis of wavetermdev/waveterm@a4447c1563 (2026-09-01). Data as JSON: /api/errors/e98a4f680abe294e. Report an issue: GitHub.