siyuan-note/siyuan · error

encoded style entity is not attached to an attribute view ri

Error message

encoded style entity is not attached to an attribute view rich text span

What it means

While restoring protected HTML style entities, the walker found a node whose style IAL contains the protection sentinel, but that node is not a plain "text" text mark. Protected style entities are only valid on text spans; style sentinels on any other node type (e.g. blockquote, heading, code block IAL) cannot be safely restored. The walker stops and rejects the payload.

Source

Thrown at kernel/av/value.go:1949

	styleReplacer := strings.NewReplacer(stylePairs...)
	literalReplacer := strings.NewReplacer(literalPairs...)
	textMarkCodeReplacer := strings.NewReplacer(textMarkCodePairs...)
	textMarkInlineMathReplacer := strings.NewReplacer(textMarkInlineMathPairs...)

	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

View on GitHub (pinned to 8641553a1f)

Solutions

  1. Remove the sentinel/style-entity token from the style attribute of the offending non-text node
  2. Move the protected style onto a text span (a node of text mark type "text") instead
  3. Re-run normalization after cleaning the rich text content; if it came from an older format, re-save the attribute view value through the current client first

Example fix

// before (non-text node carries protected style)
<span data-type="inline-code" style="color: var(--b3-font-color8)">x</span>
// after (move style to a text span)
<span data-type="text" style="color: var(--b3-font-color8)">x</span>
Defensive patterns

Strategy: validation

Validate before calling

// before sending rich text: ensure style sentinels only appear on text spans
for (const node of walkTree(tree)) {
  const style = node.ial?.style ?? ""
  if (style.includes("\ue000") && node.type !== "text") {
    throw new Error(`protected style on non-text node: ${node.type}`)
  }
}

Type guard

const isTextSpan = (node) => node.type === "text"

Try / catch

try {
  await api.normalizeAvValueText(payload)
} catch (e) {
  if (String(e).includes("not attached to an attribute view rich text span")) {
    payload = stripStyleSentinelsFromNonTextNodes(payload)
    await api.normalizeAvValueText(payload)
  }
}

Prevention

When it happens

Trigger: Calling av.NormalizeValueTextRich / NormalizeRichContent on rich text content where the style attribute of a non-text node contains a protection token (sentinel + index + \ue002), typically after content was edited by a plugin or older version that placed style sentinels outside text spans.

Common situations: Hand-written or plugin-generated Kramdown that attaches a styled IAL to a non-text node; data produced by a different SiYuan version whose entity-protection placement rules differed; corrupted .sy-derived attribute view values.

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/0e0106648461944a. Report an issue: GitHub.