siyuan-note/siyuan · error

invalid encoded style entity in attribute view rich text spa

Error message

invalid encoded style entity in attribute view rich text span

What it means

A text span's style IAL contains protection sentinel tokens, but the tokens are not valid protection markers for this restoration pass: either the same node also carries the sentinel in its text content, inline math content, or raw tokens (a node must be protected in exactly one place), or markValueTextRichStyleProtections could not match every sentinel occurrence in the style to a known protection token. This guards against malformed or forged protection tokens inside style attributes.

Source

Thrown at kernel/av/value.go:1954

	ast.Walk(tree.Root, func(node *ast.Node, entering bool) ast.WalkStatus {
		if !entering {
			return ast.WalkContinue
		}
		style := node.IALAttr("style")
		styleProtected := strings.Contains(style, sentinel)
		textProtected := ast.NodeTextMark == node.Type && strings.Contains(node.TextMarkTextContent, sentinel)
		inlineMathProtected := ast.NodeTextMark == node.Type &&
			strings.Contains(node.TextMarkInlineMathContent, sentinel)
		tokens := string(node.Tokens)
		tokensProtected := strings.Contains(tokens, sentinel)
		if styleProtected {
			if !node.IsTextMarkType("text") {
				err = fmt.Errorf("encoded style entity is not attached to an attribute view rich text span")
				return ast.WalkStop
			}
			if textProtected || inlineMathProtected || tokensProtected ||
				!markValueTextRichStyleProtections(style, sentinel, tokenIndexes, restored) {
				err = fmt.Errorf("invalid encoded style entity in attribute view rich text span")
				return ast.WalkStop
			}
			style = styleReplacer.Replace(style)
			node.SetIALAttr("style", style)
			if nil != node.Next && ast.NodeKramdownSpanIAL == node.Next.Type {
				node.Next.Tokens = parse.IAL2Tokens(node.KramdownIAL)
			}
			return ast.WalkContinue
		}
		if textProtected || inlineMathProtected {
			if !node.IsTextMarkType("code") && !node.IsTextMarkType("inline-math") {
				err = fmt.Errorf("invalid encoded style entity in attribute view rich text mark [%s]", node.TextMarkType)
				return ast.WalkStop
			}
			if tokensProtected || textProtected &&
				!markValueTextRichStyleProtections(node.TextMarkTextContent, sentinel, tokenIndexes, restored) ||
				inlineMathProtected &&
					!markValueTextRichStyleProtections(node.TextMarkInlineMathContent, sentinel, tokenIndexes, restored) {

View on GitHub (pinned to 8641553a1f)

Solutions

  1. Repair or remove the malformed protection token in the span's style attribute so it exactly matches sentinel+index+\ue002
  2. Re-generate the rich text value through the client so protection tokens are recreated consistently
  3. Ensure no sentinel substring leaks into text/math/token fields of the same node — only one protection site per node is allowed
Defensive patterns

Strategy: validation

Validate before calling

// validate every sentinel occurrence in a style is a full token
const tokenRe = /\ue000siyuan[^\ue002]*\ue002/g
const sentinels = style.match(/\ue000/g) || []
const tokens = style.match(tokenRe) || []
if (sentinels.length !== tokens.length) throw new Error("malformed style protection token")

Try / catch

try {
  await api.normalizeAvValueText(payload)
} catch (e) {
  if (String(e).includes("invalid encoded style entity in attribute view rich text span")) {
    payload = reEncodeRichText(payload)
  }
}

Prevention

When it happens

Trigger: Calling NormalizeValueTextRich with rich text where a text span's style contains a sentinel substring that is not a complete, well-formed protection token (sentinel + known index + \ue002 suffix), or a truncated/partially edited token such as a sentinel without the closing \ue002 or with an out-of-range index.

Common situations: Manual editing of exported Kramdown that split or truncated a protection token; find-and-replace across content that duplicated a sentinel fragment; plugin output that fabricated sentinel-like strings inside style attributes.

Understand the failure class

Background: "Invalid ... format", "must be in format X", "does not look like a ..." — invalid argument format errors across CLI tools and libraries — this error's family across 17 libraries.

Related errors


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