{"record":{"id":"8c32aaa3d739ed33","repo":"siyuan-note/siyuan","slug":"invalid-encoded-style-entity-in-attribute-view-ric-8c32aa","errorCode":null,"errorMessage":"invalid encoded style entity in attribute view rich text mark [%s]","messagePattern":"invalid encoded style entity in attribute view rich text mark \\[(.+?)\\]","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"kernel/av/value.go","lineNumber":1966,"sourceCode":"\t\t\tif !node.IsTextMarkType(\"text\") {\n\t\t\t\terr = fmt.Errorf(\"encoded style entity is not attached to an attribute view rich text span\")\n\t\t\t\treturn ast.WalkStop\n\t\t\t}\n\t\t\tif textProtected || inlineMathProtected || tokensProtected ||\n\t\t\t\t!markValueTextRichStyleProtections(style, sentinel, tokenIndexes, restored) {\n\t\t\t\terr = fmt.Errorf(\"invalid encoded style entity in attribute view rich text span\")\n\t\t\t\treturn ast.WalkStop\n\t\t\t}\n\t\t\tstyle = styleReplacer.Replace(style)\n\t\t\tnode.SetIALAttr(\"style\", style)\n\t\t\tif nil != node.Next && ast.NodeKramdownSpanIAL == node.Next.Type {\n\t\t\t\tnode.Next.Tokens = parse.IAL2Tokens(node.KramdownIAL)\n\t\t\t}\n\t\t\treturn ast.WalkContinue\n\t\t}\n\t\tif textProtected || inlineMathProtected {\n\t\t\tif !node.IsTextMarkType(\"code\") && !node.IsTextMarkType(\"inline-math\") {\n\t\t\t\terr = fmt.Errorf(\"invalid encoded style entity in attribute view rich text mark [%s]\", node.TextMarkType)\n\t\t\t\treturn ast.WalkStop\n\t\t\t}\n\t\t\tif tokensProtected || textProtected &&\n\t\t\t\t!markValueTextRichStyleProtections(node.TextMarkTextContent, sentinel, tokenIndexes, restored) ||\n\t\t\t\tinlineMathProtected &&\n\t\t\t\t\t!markValueTextRichStyleProtections(node.TextMarkInlineMathContent, sentinel, tokenIndexes, restored) {\n\t\t\t\terr = fmt.Errorf(\"invalid encoded style entity in attribute view rich text mark [%s]\", node.TextMarkType)\n\t\t\t\treturn ast.WalkStop\n\t\t\t}\n\t\t\tnode.TextMarkTextContent = textMarkCodeReplacer.Replace(node.TextMarkTextContent)\n\t\t\tnode.TextMarkInlineMathContent = textMarkInlineMathReplacer.Replace(node.TextMarkInlineMathContent)\n\t\t\treturn ast.WalkContinue\n\t\t}\n\t\tif !tokensProtected {\n\t\t\treturn ast.WalkContinue\n\t\t}\n\t\tswitch node.Type {\n\t\tcase ast.NodeCodeBlockCode, ast.NodeMathBlockContent, ast.NodeCodeSpanContent, ast.NodeInlineMathContent:","sourceCodeStart":1948,"sourceCodeEnd":1984,"githubUrl":"https://github.com/siyuan-note/siyuan/blob/8641553a1f07374001902d3ce773285db1292b2d/kernel/av/value.go#L1948-L1984","documentation":"A node carries the protection sentinel in its text content or inline math content, but its text mark type is neither \"code\" nor \"inline-math\". Sentinel-protected entities in TextMarkTextContent/TextMarkInlineMathContent are only restorable inside code and inline-math marks; on any other mark type the replacement would corrupt rendering, so the walker rejects the content.","triggerScenarios":"Normalizing rich text where a mark such as \"strong\", \"em\", \"a\", or \"tag\" has TextMarkTextContent or TextMarkInlineMathContent containing a protection token produced by protectValueTextRichStyleEntities.","commonSituations":"Plugin or API clients that copied protection tokens into ordinary styled text; migrating content written by tooling that misclassified mark types; round-tripping Kramdown through an external editor that changed data-type attributes.","solutions":["Change the offending mark's data-type to \"code\" or \"inline-math\", or strip the protection token from its content","Re-encode the value through the official client so entities are protected in the correct mark types","Check plugin/export tooling for code that moves TextMarkTextContent between mark types without re-running protection"],"exampleFix":"// before\n<span data-type=\"strong\">see siyuan...0</span>\n// after\n<span data-type=\"code\">see &amp;lt;</span>","handlingStrategy":"validation","validationCode":"const allowed = new Set([\"code\", \"inline-math\"])\nfor (const mark of textMarks(tree)) {\n  if ((mark.textContent + mark.inlineMathContent).includes(\"\\ue000\") && !allowed.has(mark.dataType)) {\n    throw new Error(`sentinel in disallowed mark type: ${mark.dataType}`)\n  }\n}","typeGuard":"const isCodeOrMathMark = (mark) => mark.dataType === \"code\" || mark.dataType === \"inline-math\"","tryCatchPattern":"try {\n  await api.normalizeAvValueText(payload)\n} catch (e) {\n  if (String(e).includes(\"invalid encoded style entity in attribute view rich text mark\")) {\n    payload = moveSentinelContentToCodeMarks(payload)\n  }\n}","preventionTips":["Keep protected entities only in code/inline-math marks","Audit plugins that rewrite mark data-type attributes","Strip private-use sentinel characters from external content before import"],"tags":["attribute-view","rich-text","text-mark","validation"],"backgroundTag":"schema-validation-failed","analyzedSha":"8641553a1f07374001902d3ce773285db1292b2d","analyzedAt":"2026-09-11T16:08:28.414Z","contentChangedAt":"2026-09-11T16:08:28.414Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}