siyuan-note/siyuan · error

invalid color [%s]

Error message

invalid color [%s]

What it means

Thrown by validateOptionalBootAppearanceColor when a color field is non-empty but does not match bootAppearanceColorPattern, a hex color of 3, 4, 6, or 8 hex digits prefixed by '#'. Empty means unset and is allowed; anything else must be valid hex (no rgb(), names, or uppercase-invalid formats).

Source

Thrown at kernel/model/boot_appearance.go:735

			continue
		}
		if !seen[normalized] {
			seen[normalized] = true
			frontends = append(frontends, normalized)
		}
	}
	if len(frontends) == 0 && len(manifestFrontends) == 0 && len(pluginFrontends) == 0 {
		frontends = append(frontends, "desktop", "mobile")
	}
	if len(frontends) == 0 {
		return nil, errors.New("no supported frontend")
	}
	return frontends, nil
}

func validateOptionalBootAppearanceColor(color string) error {
	if color != "" && !bootAppearanceColorPattern.MatchString(color) {
		return fmt.Errorf("invalid color [%s]", color)
	}
	return nil
}

func isValidBootAppearanceID(id string) bool {
	return len(id) <= 64 && bootAppearanceIDPattern.MatchString(id)
}

func isSafeBootAppearanceRelativePath(relativePath string) bool {
	if relativePath == "" || len(relativePath) > maxBootAppearancePathLength || strings.Contains(relativePath, "\\") ||
		strings.ContainsAny(relativePath, `<>:"|?*`) || strings.HasPrefix(relativePath, "/") ||
		filepath.IsAbs(relativePath) || filepath.VolumeName(relativePath) != "" {
		return false
	}
	segments := strings.Split(relativePath, "/")
	if len(segments) > maxBootAppearancePathDepth {
		return false
	}

View on GitHub (pinned to 8641553a1f)

Solutions

  1. Convert the value to hex notation: #RGB, #RGBA, #RRGGBB, or #RRGGBBAA (e.g. rgb(255,0,0) -> #ff0000).
  2. Add the missing '#' prefix if it was omitted.
  3. Remove the field to accept the default styling.

Example fix

// before
"color": "rgb(20, 30, 40)"
// after
"color": "#141e28"
Defensive patterns

Strategy: validation

Validate before calling

function validOptionalColor(c) { return !c || /^#(?:[0-9a-fA-F]{3}|[0-9a-fA-F]{4}|[0-9a-fA-F]{6}|[0-9a-fA-F]{8})$/.test(c); }

Type guard

const isHexColor = (v) => typeof v === "string" && /^#(?:[0-9a-fA-F]{3}|[0-9a-fA-F]{4}|[0-9a-fA-F]{6}|[0-9a-fA-F]{8})$/.test(v);

Try / catch

try { await installBootAppearance(pkg); } catch (e) { if (String(e).includes("invalid color")) { /* convert the color to hex notation */ } else throw e; }

Prevention

When it happens

Trigger: A manifest color like "red", "rgb(255,0,0)", "#GGGGGG", or "ffffff" (missing '#') encountered during loadBootAppearance.

Common situations: Authors using CSS color names or functional notations, dropping the '#' prefix, or exporting colors with alpha as "#11223344;0.5" style strings.

Understand the failure class

Background: "Invalid ... format", "must be in format X", "does not look like a ..." — invalid argument format errors across CLI tools and libraries — this error's family across 17 libraries.

Related errors


AI-assisted analysis of siyuan-note/siyuan@8641553a1f (2026-09-11). Data as JSON: /api/errors/ebbc3a11c5023989. Report an issue: GitHub.