siyuan-note/siyuan · error

duplicate inline style ID [%s]

Error message

duplicate inline style ID [%s]

What it means

Inline style IDs must be unique within the workspace style list because the editor references styles by ID. normalizeInlineStyles tracks seen IDs and aborts the entire save/load when two entries share the same ID, preventing ambiguous style resolution.

Source

Thrown at kernel/model/inline_style.go:667

	for _, style := range styles {
		if style == nil {
			return nil, errors.New("inline style must not be null")
		}

		id := strings.TrimSpace(style.ID)
		if id == "" && generateIDs {
			for {
				id = ast.NewNodeID()
				if _, exists := ids[id]; !exists {
					break
				}
			}
		}
		if !ast.IsNodeIDPattern(id) {
			return nil, fmt.Errorf("invalid inline style ID [%s]", id)
		}
		if _, exists := ids[id]; exists {
			return nil, fmt.Errorf("duplicate inline style ID [%s]", id)
		}
		ids[id] = struct{}{}

		name := strings.TrimSpace(style.Name)
		if name == "" {
			return nil, errors.New("inline style name must not be empty")
		}
		if maxInlineStyleNameRunes < utf8.RuneCountInString(name) {
			return nil, fmt.Errorf("inline style name exceeds the %d character limit", maxInlineStyleNameRunes)
		}
		if style.Light == nil || style.Dark == nil {
			return nil, fmt.Errorf("inline style [%s] must define light and dark themes", id)
		}

		light, err := normalizeInlineStyleTheme(style.Light)
		if err != nil {
			return nil, fmt.Errorf("invalid light theme of inline style [%s]: %w", id, err)
		}

View on GitHub (pinned to 8641553a1f)

Solutions

  1. Reassign one of the duplicates a fresh unique node-ID-format ID before saving.
  2. Deduplicate the list before the API call (keep one entry per ID).
  3. Edit the on-disk inline-styles JSON and change or drop the duplicated entry so loadInlineStyles succeeds.

Example fix

// before
styles := []*InlineStyle{
  {ID: "20240101120000-abcdefg", Name: "Red"},
  {ID: "20240101120000-abcdefg", Name: "Red copy"},
}
// after
styles := []*InlineStyle{
  {ID: "20240101120000-abcdefg", Name: "Red"},
  {ID: "20240101120100-ghijklm", Name: "Red copy"},
}
Defensive patterns

Strategy: validation

Validate before calling

const ids = styles.map(s => s.ID.trim()); if (new Set(ids).size !== ids.length) throw new Error('duplicate style IDs');

Try / catch

try { await saveStyles(styles) } catch (e) { if (/duplicate inline style ID/.test(String(e))) { /* deduplicate or regenerate the duplicated ID, then retry */ } }

Prevention

When it happens

Trigger: setInlineStylesData receives a list where two or more InlineStyle entries have the same (trimmed) ID; loadInlineStyles reads a config file containing duplicated IDs, e.g. from a copy-paste or a bad merge/sync of the inline-styles JSON.

Common situations: Duplicating an existing custom style by copying its JSON entry without changing the ID; concurrent clients writing style lists that both contain the same generated ID; restoring a merged config file.

Understand the failure class

Background: Schema validation failed / invalid input schema: payload rejected because its shape doesn't match the expected schema — this error's family across 28 libraries.

Related errors


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