siyuan-note/siyuan · error

color [%s] must use #RRGGBB format

Error message

color [%s] must use #RRGGBB format

What it means

normalizeInlineStyleColor trims and lowercases the input, allows an empty string, and otherwise requires an exact match of the inlineStyleColorPattern — a 6-digit hex color in #RRGGBB form. Anything else (3-digit hex, named colors, rgb(), missing #, wrong length) fails with this message showing the original input.

Source

Thrown at kernel/model/inline_style.go:870

func normalizeInlineStyleTheme(theme *InlineStyleTheme) (ret *InlineStyleTheme, err error) {
	ret = &InlineStyleTheme{}
	if ret.Color, err = normalizeInlineStyleColor(theme.Color); err != nil {
		return nil, fmt.Errorf("invalid color: %w", err)
	}
	if ret.BackgroundColor, err = normalizeInlineStyleColor(theme.BackgroundColor); err != nil {
		return nil, fmt.Errorf("invalid backgroundColor: %w", err)
	}
	return ret, nil
}

func normalizeInlineStyleColor(color string) (ret string, err error) {
	ret = strings.ToLower(strings.TrimSpace(color))
	if ret == "" {
		return ret, nil
	}
	if !inlineStyleColorPattern.MatchString(ret) {
		return "", fmt.Errorf("color [%s] must use #RRGGBB format", color)
	}
	return ret, nil
}

func init() {
	av.LoadWorkspacePalette = loadWorkspaceAVPalette
}

func loadWorkspaceAVPalette() (colors []*av.AttributeViewCustomColor, order []string) {
	waitForSyncingStorages()
	inlineStylesLock.Lock()
	defer inlineStylesLock.Unlock()
	if workspaceAVPaletteCache == nil || workspaceAVPaletteCachePath != inlineStylesPath() {
		styles, err := loadInlineStyles()
		if err != nil {
			return nil, nil
		}
		cacheWorkspaceAVPalette(styles.AV)

View on GitHub (pinned to 8641553a1f)

Solutions

  1. Normalize the value to exactly 7 characters: '#', then 6 lowercase hex digits (e.g. #1e90ff).
  2. Expand #RGB shorthand to #RRGGBB and strip any trailing ';' or whitespace.
  3. Test the value against the regex /^#[0-9a-fA-F]{6}$/ client-side before submitting.

Example fix

// before
color = "#fff";
saveTheme(color);
// after
color = "#ffffff";
if (!/^#[0-9a-fA-F]{6}$/.test(color)) throw new Error("bad color");
saveTheme(color);
Defensive patterns

Strategy: validation

Validate before calling

function toHexColor(input) {
  const s = String(input).trim().toLowerCase();
  if (s === "") return "";
  const m = /^#([0-9a-f]{6})$/.exec(s) || /^#([0-9a-f])([0-9a-f])([0-9a-f])$/.exec(s);
  if (!m) throw new Error(`color [${input}] must use #RRGGBB format`);
  return m.length === 4 ? "#" + m[1] + m[2] + m[3] : s;
}

Try / catch

try {
  saveInlineStyleTheme(theme);
} catch (e) {
  if (String(e.message).includes("must use #RRGGBB format")) {
    // re-prompt for a valid hex color
  } else { throw e; }
}

Prevention

When it happens

Trigger: Any theme save where Color or BackgroundColor is a non-empty string not matching ^#[0-9a-f]{6}$ (after trim/lowercase), raised at the normalizeInlineStyleColor call in kernel/model/inline_style.go.

Common situations: Users pasting colors from design tools as rgb()/hsl(); shorthand #fff values; uppercase #AABBCC is fine (lowercased) but 5- or 7-character typos are not; HTML attribute values like "#AABBCC;" with trailing semicolons.

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/5ff6c24b58d8afff. Report an issue: GitHub.