siyuan-note/siyuan · error

duplicate builtin style ID [%s]

Error message

duplicate builtin style ID [%s]

What it means

Two entries in the builtin styles array share the same ID (after trimming whitespace). The four builtin style IDs must each appear at most once because they are keys into the fixed error/warning/info/success set and their order is defined by builtinStyleOrder.

Source

Thrown at kernel/model/inline_style.go:744

			return nil, err
		}
		ret.Colors = append(ret.Colors, &InlineStyleBuiltinColor{Index: color.Index, Light: light, Dark: dark})
	}
	sort.Slice(ret.Colors, func(i, j int) bool {
		return ret.Colors[i].Index < ret.Colors[j].Index
	})

	styleIDs := make(map[string]struct{}, len(builtin.Styles))
	for _, style := range builtin.Styles {
		if style == nil {
			return nil, errors.New("builtin style must not be null")
		}
		id := strings.TrimSpace(style.ID)
		if _, valid := builtinStyleOrder[id]; !valid {
			return nil, fmt.Errorf("invalid builtin style ID [%s]", id)
		}
		if _, exists := styleIDs[id]; exists {
			return nil, fmt.Errorf("duplicate builtin style ID [%s]", id)
		}
		styleIDs[id] = struct{}{}

		light, dark, err := normalizeInlineStyleThemePair(style.Light, style.Dark, "builtin style ["+id+"]")
		if err != nil {
			return nil, err
		}
		ret.Styles = append(ret.Styles, &InlineStyleBuiltinStyle{ID: id, Light: light, Dark: dark})
	}
	sort.Slice(ret.Styles, func(i, j int) bool {
		return builtinStyleOrder[ret.Styles[i].ID] < builtinStyleOrder[ret.Styles[j].ID]
	})

	if builtin.Hidden != nil {
		if ret.Hidden.Color, err = normalizeHiddenBuiltinColorIndexes(builtin.Hidden.Color, "color"); err != nil {
			return nil, err
		}
		if ret.Hidden.BackgroundColor, err = normalizeHiddenBuiltinColorIndexes(builtin.Hidden.BackgroundColor,

View on GitHub (pinned to 8641553a1f)

Solutions

  1. Delete the duplicate entry for that builtin style ID in inline-styles.json or the API payload.
  2. If the two entries differ, keep the desired one and merge its theme values into the single surviving entry.
  3. Add a de-dup step (map keyed by trimmed ID) in any tooling that writes the builtin styles array.

Example fix

// before
[{"id": "info", ...}, {"id": "info", ...}]
// after
[{"id": "info", ...}]
Defensive patterns

Strategy: validation

Validate before calling

const ids = config.builtin.styles.map(s => (s.id || "").trim());
if (new Set(ids).size !== ids.length) {
  throw new Error("duplicate builtin style id");
}

Prevention

When it happens

Trigger: setInlineStylesData or loadInlineStyles with builtin.styles containing two entries whose trimmed ids match, e.g. two `{"id": "info"}` entries.

Common situations: Duplicated JSON object from copy-paste; merging configs from two sources without de-duplication; a script iterating a list that already contained the style and appending it again.

Understand the failure class

Background: "Invalid value" and "allowed values are" config errors: what your library rejected and how to fix it — this error's family across 41 libraries.

Related errors


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