siyuan-note/siyuan · error

unsupported attribute view rich text spec [%d]

Error message

unsupported attribute view rich text spec [%d]

What it means

parseValueTextRich in kernel/av/value.go parses an attribute-view rich-text payload only if its Spec integer equals the compile-time ValueTextRichSpec constant the kernel supports. A payload written by a different (older or newer) spec version is rejected with this error rather than parsed speculatively, protecting the sanitizer and renderer from unknown markup semantics.

Source

Thrown at kernel/av/value.go:561

}

// IsRich 返回文本值是否包含富文本源。
func (value *ValueText) IsRich() bool {
	return nil != value && nil != value.Rich
}

// ParseValueTextRich 校验并解析文本字段的富文本源。
func ParseValueTextRich(rich *ValueTextRich) (tree *parse.Tree, err error) {
	_, tree, err = parseValueTextRich(rich)
	return
}

func parseValueTextRich(rich *ValueTextRich) (blockDOM string, tree *parse.Tree, err error) {
	if nil == rich {
		return
	}
	if ValueTextRichSpec != rich.Spec {
		err = fmt.Errorf("unsupported attribute view rich text spec [%d]", rich.Spec)
		return
	}
	if ValueTextRichFormatKramdown != rich.Format {
		err = fmt.Errorf("unsupported attribute view rich text format [%s]", rich.Format)
		return
	}

	luteEngine := newValueTextRichLute()
	content, protectedStyleEntities, protectErr := protectValueTextRichKramdownStyleEntities(rich.Content)
	if nil != protectErr {
		err = protectErr
		return
	}
	blockDOM, tree = luteEngine.Md2BlockDOMTree(content, true)
	if nil == tree || nil == tree.Root {
		err = fmt.Errorf("parse attribute view rich text failed")
		return
	}

View on GitHub (pinned to 8641553a1f)

Solutions

  1. Upgrade (or reinstall) the SiYuan kernel so ValueTextRichSpec matches the data's spec
  2. Set rich.Spec = av.ValueTextRichSpec when constructing the payload programmatically
  3. Re-save the cell in the UI so the kernel rewrites the rich text with the current spec
  4. Restore the affected data from a backup made under the matching version

Example fix

// before
rich := &av.ValueTextRich{Spec: 1, Format: av.ValueTextRichFormatKramdown, Content: "**hi"}
// after
rich := &av.ValueTextRich{Spec: av.ValueTextRichSpec, Format: av.ValueTextRichFormatKramdown, Content: "**hi"}
Defensive patterns

Strategy: type-guard

Validate before calling

if rich.Spec != av.ValueTextRichSpec { return fmt.Errorf("spec %d != %d", rich.Spec, av.ValueTextRichSpec) }

Type guard

func isCurrentSpec(r *av.ValueTextRich) bool { return r != nil && r.Spec == av.ValueTextRichSpec }

Try / catch

if err != nil && strings.Contains(err.Error(), "unsupported attribute view rich text spec") {
    // data from another version: route through re-save/upgrade path
}

Prevention

When it happens

Trigger: Calling ParseValueTextRich, NormalizeValueTextRich, or normalizeValueTextRichTreeSource with a ValueTextRich whose Spec field differs from ValueTextRichSpec — typically data persisted by another SiYuan version or hand-crafted rich-text values with a guessed spec number.

Common situations: Downgrading SiYuan after a rich-text spec bump; copying database content between workspaces of different versions; tests or plugins constructing ValueTextRich literals with a hardcoded wrong Spec.

Understand the failure class

Background: "is not a compatible type" / "cannot merge" errors: when a value's type doesn't match what the library requires — this error's family across 65 libraries.

Related errors


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