wavetermdev/waveterm · error

invalid hex color: %v

Error message

invalid hex color: %v

What it means

The value passed the '#' and length checks, but hex.DecodeString failed because the digits are not valid hexadecimal (e.g. '#GGHHII'). The underlying encoding/hex error is wrapped with "invalid hex color: %v".

Source

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

	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
}

func setBgRun(cmd *cobra.Command, args []string) (rtnErr error) {
	defer func() {
		sendActivity("setbg", rtnErr == nil)
	}()

View on GitHub (pinned to a4447c1563)

Solutions

  1. Use only characters 0-9 and A-F (case-insensitive) in the hex portion.
  2. Validate locally: `python3 -c "int('GGGGGG',16)"` or an online hex checker to confirm.
  3. Re-type the value rather than pasting to eliminate hidden characters; or use a CSS color name instead.

Example fix

// before
wsh setbg '#GGGGGG'
// after
wsh setbg '#GGGGGG'  ->  wsh setbg '#999999'
Defensive patterns

Strategy: validation

Validate before calling

hexPart := strings.TrimPrefix(color, "#")
if _, err := hex.DecodeString(hexPart); err != nil {
    return fmt.Errorf("color %q contains non-hex characters", color)
}

Type guard

var hexRe = regexp.MustCompile(`^#[0-9a-fA-F]{6}([0-9a-fA-F]{2})?$`)
func isHexColor(c string) bool { return hexRe.MatchString(c) }

Try / catch

if err := validateHexColor(c); err != nil {
    if strings.Contains(err.Error(), "invalid hex color") { /* re-prompt or fall back to a CSS name */ }
}

Prevention

When it happens

Trigger: Calling `wsh setbg --border-color '#GGGGGG'` or any 6/8-character string after '#' containing non-hex characters (g-z, symbols, spaces).

Common situations: Typos like #0O0OOO (letter O vs zero); pasting a placeholder such as #RRGGBB literally; hidden whitespace or unicode characters pasted into the argument.

Related errors


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