{"record":{"id":"2a6aa05c2c793da2","repo":"siyuan-note/siyuan","slug":"invalid-inline-style-id-s","errorCode":null,"errorMessage":"invalid inline style ID [%s]","messagePattern":"invalid inline style ID \\[(.+?)\\]","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"kernel/model/inline_style.go","lineNumber":664,"sourceCode":"\t}\n\tret = make([]*InlineStyle, 0, len(styles))\n\tids := make(map[string]struct{}, len(styles))\n\tfor _, style := range styles {\n\t\tif style == nil {\n\t\t\treturn nil, errors.New(\"inline style must not be null\")\n\t\t}\n\n\t\tid := strings.TrimSpace(style.ID)\n\t\tif id == \"\" && generateIDs {\n\t\t\tfor {\n\t\t\t\tid = ast.NewNodeID()\n\t\t\t\tif _, exists := ids[id]; !exists {\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tif !ast.IsNodeIDPattern(id) {\n\t\t\treturn nil, fmt.Errorf(\"invalid inline style ID [%s]\", id)\n\t\t}\n\t\tif _, exists := ids[id]; exists {\n\t\t\treturn nil, fmt.Errorf(\"duplicate inline style ID [%s]\", id)\n\t\t}\n\t\tids[id] = struct{}{}\n\n\t\tname := strings.TrimSpace(style.Name)\n\t\tif name == \"\" {\n\t\t\treturn nil, errors.New(\"inline style name must not be empty\")\n\t\t}\n\t\tif maxInlineStyleNameRunes < utf8.RuneCountInString(name) {\n\t\t\treturn nil, fmt.Errorf(\"inline style name exceeds the %d character limit\", maxInlineStyleNameRunes)\n\t\t}\n\t\tif style.Light == nil || style.Dark == nil {\n\t\t\treturn nil, fmt.Errorf(\"inline style [%s] must define light and dark themes\", id)\n\t\t}\n\n\t\tlight, err := normalizeInlineStyleTheme(style.Light)","sourceCodeStart":646,"sourceCodeEnd":682,"githubUrl":"https://github.com/siyuan-note/siyuan/blob/8641553a1f07374001902d3ce773285db1292b2d/kernel/model/inline_style.go#L646-L682","documentation":"Every inline style must carry an ID matching the SiYuan node-ID pattern (ast.IsNodeIDPattern, typically 14 digits + '-' + 7 alphanumeric chars). If the trimmed ID is empty and generateIDs is false, or the provided ID does not match the pattern, normalization fails so that stored style references stay resolvable.","triggerScenarios":"Calling setInlineStylesData with an InlineStyle whose ID is empty while generateIDs is false, or whose ID is an arbitrary string like \"my-style\" or contains whitespace/illegal characters; also triggered when loading a config file with hand-made IDs.","commonSituations":"Custom-style entries created by scripts or plugins using human-friendly slugs instead of node-ID-format IDs; manually editing the inline-styles JSON; older configs written before the ID pattern check was added.","solutions":["Give the style a valid node-ID-format ID (yyymmddhhmmss-xxxxxxx) or clear the ID and let the system generate one (generateIDs=true path).","Trim the ID — leading/trailing whitespace is trimmed first, but embedded whitespace still fails the pattern.","Regenerate IDs for existing entries with a script that rewrites the inline-styles JSON to valid node IDs."],"exampleFix":"// before\nstyle := &InlineStyle{ID: \"highlight-red\", Name: \"Red\"}\n// after\nstyle := &InlineStyle{ID: \"20240101120000-abcdefg\", Name: \"Red\"} // or ID: \"\" with generateIDs enabled","handlingStrategy":"validation","validationCode":"const idPattern = /^\\d{14}-[0-9a-z]{7}$/; for (const s of styles) { if (!idPattern.test(s.ID.trim())) throw new Error(`bad style ID: ${s.ID}`); }","typeGuard":"const hasValidId = (s: InlineStyle): boolean => /^\\d{14}-[0-9a-z]{7}$/.test(s.ID.trim());","tryCatchPattern":"try { await saveStyles(styles) } catch (e) { if (/invalid inline style ID/.test(String(e))) { styles = styles.map(s => ({...s, ID: s.ID.trim()})); /* regenerate or fix IDs, then retry */ } }","preventionTips":["Generate IDs with the same node-ID routine the app uses instead of inventing slugs","Trim IDs before submitting","Keep a validator for the yyymmddhhmmss-xxxxxxx pattern in any external tooling"],"tags":["validation","identifier","inline-styles","format"],"backgroundTag":"invalid-identifier-format","analyzedSha":"8641553a1f07374001902d3ce773285db1292b2d","analyzedAt":"2026-09-11T16:08:28.414Z","contentChangedAt":"2026-09-11T16:08:28.414Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}