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
- Convert the value to hex notation: #RGB, #RGBA, #RRGGBB, or #RRGGBBAA (e.g. rgb(255,0,0) -> #ff0000).
- Add the missing '#' prefix if it was omitted.
- 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
- Use hex notation only (#RGB/#RGBA/#RRGGBB/#RRGGBBAA)
- Never use CSS color names or rgb() in manifests
- Omit the field if default styling is acceptable
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
- 199
- invalid marketplace package manifest
- too many layers: %d
- invalid or duplicate layer ID
- unsupported layer type [%s]
AI-assisted analysis of siyuan-note/siyuan@8641553a1f (2026-09-11).
Data as JSON: /api/errors/ebbc3a11c5023989.
Report an issue: GitHub.