wavetermdev/waveterm · error

invalid color %q: must be a hex color (#RRGGBB or #RRGGBBAA)

Error message

invalid color %q: must be a hex color (#RRGGBB or #RRGGBBAA) or a CSS color name

What it means

validateColor accepts either a '#' hex color (delegated to validateHexColor) or a name present in the CssColorNames set. Anything else — invented names, misspelled CSS names, arbitrary strings — fails with this message telling you the two accepted forms.

Source

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

		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)
	}()

	borderColorChanged := cmd.Flags().Changed("border-color")
	activeBorderColorChanged := cmd.Flags().Changed("active-border-color")

	if borderColorChanged {
		if err := validateColor(setBgBorderColor); err != nil {
			return fmt.Errorf("--border-color: %v", err)
		}
	}
	if activeBorderColorChanged {

View on GitHub (pinned to a4447c1563)

Solutions

  1. Use an exact CSS color name (e.g. 'red', 'teal', 'darkgray') or a hex value '#RRGGBB'/'#RRGGBBAA'.
  2. Check spelling against the CSS color name list; prefer hex to avoid name ambiguity.
  3. Quote multi-word values and avoid spaces — use hex instead.
  4. If you intended hex, don't forget the leading '#' so it routes to validateHexColor.

Example fix

// before
wsh setbg navyblue
// after
wsh setbg navy
Defensive patterns

Strategy: validation

Validate before calling

if !strings.HasPrefix(color, "#") && !CssColorNames[strings.ToLower(color)] {
    return fmt.Errorf("%q is neither a hex color nor a CSS color name", color)
}

Type guard

func isAcceptableColor(c string) bool {
    if strings.HasPrefix(c, "#") { return regexp.MustCompile(`^#[0-9a-fA-F]{6}([0-9a-fA-F]{2})?$`).MatchString(c) }
    return CssColorNames[strings.ToLower(c)]
}

Try / catch

if err := validateColor(c); err != nil {
    var suggest string
    if d := nearestCssName(c); d != "" { suggest = d }
    return fmt.Errorf("%v (did you mean %q?)", err, suggest)
}

Prevention

When it happens

Trigger: Calling `wsh setbg navyblue`, `wsh setbg "dark gray"` (not a valid CSS name, and contains a space), or any positional/flag color value that is neither '#' hex nor an exact CSS color name.

Common situations: Misspelling CSS names ('grey' vs 'gray' is fine, 'blueish' is not); using brand colors by name; forgetting quotes around multi-word names.

Related errors


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