{"record":{"id":"1453fae0c2b77c79","repo":"siyuan-note/siyuan","slug":"attribute-view-rich-text-style-entity-was-not-rest","errorCode":null,"errorMessage":"attribute view rich text style entity was not restored","messagePattern":"attribute view rich text style entity was not restored","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"kernel/av/value.go","lineNumber":2001,"sourceCode":"\t\tswitch node.Type {\n\t\tcase ast.NodeCodeBlockCode, ast.NodeMathBlockContent, ast.NodeCodeSpanContent, ast.NodeInlineMathContent:\n\t\t\tif !markValueTextRichStyleProtections(tokens, sentinel, tokenIndexes, restored) {\n\t\t\t\terr = fmt.Errorf(\"invalid encoded style entity in attribute view rich text node [%s]\", node.Type.String())\n\t\t\t\treturn ast.WalkStop\n\t\t\t}\n\t\t\tnode.Tokens = []byte(literalReplacer.Replace(tokens))\n\t\tdefault:\n\t\t\terr = fmt.Errorf(\"invalid encoded style entity in attribute view rich text node [%s]\", node.Type.String())\n\t\t\treturn ast.WalkStop\n\t\t}\n\t\treturn ast.WalkContinue\n\t})\n\tif nil != err {\n\t\treturn\n\t}\n\tfor _, found := range restored {\n\t\tif !found {\n\t\t\treturn fmt.Errorf(\"attribute view rich text style entity was not restored\")\n\t\t}\n\t}\n\tast.Walk(tree.Root, func(node *ast.Node, entering bool) ast.WalkStatus {\n\t\tif entering && valueTextRichNodeContainsSentinel(node, sentinel) {\n\t\t\terr = fmt.Errorf(\"attribute view rich text style entity sentinel was not removed from node [%s]\",\n\t\t\t\tnode.Type.String())\n\t\t\treturn ast.WalkStop\n\t\t}\n\t\treturn ast.WalkContinue\n\t})\n\treturn\n}\n\nfunc valueTextRichNodeContainsSentinel(node *ast.Node, sentinel string) bool {\n\tvalues := []string{\n\t\tnode.ID, node.Spec, node.Data, string(node.Tokens), string(node.CodeBlockOpenFence),\n\t\tstring(node.CodeBlockInfo), string(node.CodeBlockCloseFence), string(node.LinkRefLabel),\n\t\tstring(node.FootnotesRefLabel), node.FootnotesRefId, string(node.HtmlEntityTokens),","sourceCodeStart":1983,"sourceCodeEnd":2019,"githubUrl":"https://github.com/siyuan-note/siyuan/blob/8641553a1f07374001902d3ce773285db1292b2d/kernel/av/value.go#L1983-L2019","documentation":"After walking the tree and applying all replacements, at least one protection entry was never marked as restored: its token never appeared (in a valid form) anywhere in the tree. Every protection created during the protect phase must be consumed exactly once; an unconsumed token means content was lost or the tree does not correspond to the protection set.","triggerScenarios":"Normalizing rich text where the protect pass created tokens for style entities but a later parse/render step dropped or transformed the containing node (e.g. Lute normalized away the styled span), leaving the token unused.","commonSituations":"Style entities inside constructs that get rewritten during Kramdown round-tripping (e.g. invalid HTML that the parser discards); content where a styled span was removed by normalization before restoration ran.","solutions":["Inspect the rich text for styled spans that the Kramdown parser drops or rewrites (malformed HTML, unsupported attributes) and fix them","Re-author the value so protected entities live in constructs that survive a parse/render round trip","Verify the protection set matches the tree actually being restored (same pass, same content)"],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":"// pre-check: styled spans must be constructs the Kramdown parser preserves\nfor (const span of styledSpans(tree)) {\n  if (!/^<span\\s+[^>]*style=/.test(span.raw)) {\n    throw new Error(\"styled content uses a construct that may not round-trip\")\n  }\n}","typeGuard":null,"tryCatchPattern":"try {\n  await api.normalizeAvValueText(payload)\n} catch (e) {\n  if (String(e).includes(\"style entity was not restored\")) {\n    payload = rebuildRichTextWithoutDroppedSpans(payload)\n    await api.normalizeAvValueText(payload)\n  }\n}","preventionTips":["Author rich text only with supported Kramdown constructs","Fix malformed HTML spans that the parser silently drops","Test round-trip stability of complex styled content before saving"],"tags":["attribute-view","rich-text","round-trip","data-loss"],"backgroundTag":"internal-invariant-violation","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"}