siyuan-note/siyuan · error

invalid table cell rich text document spec

Error message

invalid table cell rich text document spec [%s]

What it means

A NodeTableCell carrying rich text is only legal in a document whose spec version is >= 4, with the node type NodeTableCell, while walking inside a table row context. If any of these conditions fails (e.g. the document declares an older spec but still embeds TableCellRich), this error is thrown with the offending spec string.

Solutions

  1. Use a kernel version that supports TableCellRichDocumentSpec "4" or later.
  2. Ensure the document's spec attribute is "4" wherever TableCellRich is present.
  3. Fix the producer so TableCellRich appears only on NodeTableCell nodes inside table rows.

Example fix

// before (producer)
spec = "3"; node.TableCellRich = rich
// after
spec = "4"; node.Type = "NodeTableCell"; node.TableCellRich = rich // emitted under a row
Defensive patterns

Strategy: validation

Validate before calling

if parseInt(docSpec) < 4 && docContainsTableCellRich(doc) { /* upgrade producer/kernel or strip rich text before loading */ }

Prevention

When it happens

Trigger: checkTableCellRichJSON encounters TableCellRich on a node when the document spec is "3" or lower, the node type is not "NodeTableCell", or the walk context is not "row" (e.g. cell data placed outside a row).

Common situations: Importing a newer-format document into an older kernel version that declares a lower spec; a generator emitting TableCellRich on wrong node types or outside table rows; hand-edited .sy files.

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@9f775e8a12 (2026-09-19). Data as JSON: /api/errors/cfaabaf385bf100b. Report an issue: GitHub.

Appendix: source

Thrown at kernel/treenode/table_cell_rich.go:37

func checkTableCellRichJSON(data []byte, spec string) error {
	type rawNode struct {
		Type          string
		TableCellRich json.RawMessage
		Children      []json.RawMessage
	}
	var check func(json.RawMessage, string) error
	check = func(raw json.RawMessage, context string) error {
		var node rawNode
		if err := json.Unmarshal(raw, &node); nil != err {
			return err
		}
		if len(node.TableCellRich) > 0 {
			if !utf8.Valid(node.TableCellRich) {
				return fmt.Errorf("table cell rich text payload is not UTF-8")
			}
			version, _ := strconv.Atoi(spec)
			if version < 4 || node.Type != "NodeTableCell" || context != "row" {
				return fmt.Errorf("invalid table cell rich text document spec [%s]", spec)
			}
			var fields map[string]json.RawMessage
			if err := json.Unmarshal(node.TableCellRich, &fields); nil != err || len(fields) != 3 {
				return fmt.Errorf("invalid table cell rich text payload")
			}
			for _, name := range []string{"spec", "format", "content"} {
				if len(fields[name]) == 0 || bytes.Equal(bytes.TrimSpace(fields[name]), []byte("null")) {
					return fmt.Errorf("missing table cell rich text field [%s]", name)
				}
			}
			var rich ast.TableCellRich
			if err := json.Unmarshal(node.TableCellRich, &rich); nil != err {
				return err
			}
			if _, err := av.ParseTableCellRich(&rich); nil != err {
				return err
			}
		}

View on GitHub (pinned to 9f775e8a12)