{"record":{"id":"fa5e3b1b62cea0b1","repo":"siyuan-note/siyuan","slug":"table-cell-rich-text-projection-marker-changed","errorCode":null,"errorMessage":"table cell rich text projection marker changed","messagePattern":"table cell rich text projection marker changed","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"kernel/treenode/table_cell_rich.go","lineNumber":160,"sourceCode":"\t\tif !entering || nil == cell.TableCellRich {\n\t\t\treturn ast.WalkContinue\n\t\t}\n\t\tvar fragment *parse.Tree\n\t\tif fragment, err = av.ParseTableCellRich(cell.TableCellRich); nil != err {\n\t\t\treturn ast.WalkStop\n\t\t}\n\t\texpected, sources := parse.ProjectTableCellRichWithSources(fragment)\n\t\tchanged := false\n\t\tvar sync func(*ast.Node, *ast.Node) error\n\t\tsync = func(want, actual *ast.Node) error {\n\t\t\tfor ; want != nil && actual != nil; want, actual = want.Next, actual.Next {\n\t\t\t\tif want.Type != actual.Type {\n\t\t\t\t\treturn fmt.Errorf(\"table cell rich text projection structure changed\")\n\t\t\t\t}\n\t\t\t\tif !bytes.Equal(tableCellInlineSignature(want), tableCellInlineSignature(actual)) {\n\t\t\t\t\torigin := sources[want]\n\t\t\t\t\tif nil == origin {\n\t\t\t\t\t\treturn fmt.Errorf(\"table cell rich text projection marker changed\")\n\t\t\t\t\t}\n\t\t\t\t\tswitch origin.Type {\n\t\t\t\t\tcase ast.NodeCodeBlockCode:\n\t\t\t\t\t\torigin.Tokens = []byte(html.UnescapeString(actual.TextMarkTextContent) + \"\\n\")\n\t\t\t\t\tcase ast.NodeMathBlockContent:\n\t\t\t\t\t\torigin.Tokens = []byte(html.UnescapeString(actual.TextMarkInlineMathContent))\n\t\t\t\t\tdefault:\n\t\t\t\t\t\tparent, previous, next, first, last := origin.Parent, origin.Previous, origin.Next, origin.FirstChild, origin.LastChild\n\t\t\t\t\t\t*origin = *parse.CloneTableCellInline(actual)\n\t\t\t\t\t\torigin.Parent, origin.Previous, origin.Next, origin.FirstChild, origin.LastChild = parent, previous, next, first, last\n\t\t\t\t\t}\n\t\t\t\t\tchanged = true\n\t\t\t\t}\n\t\t\t\tif e := sync(want.FirstChild, actual.FirstChild); nil != e {\n\t\t\t\t\treturn e\n\t\t\t\t}\n\t\t\t}\n\t\t\tif want != nil || actual != nil {","sourceCodeStart":142,"sourceCodeEnd":178,"githubUrl":"https://github.com/siyuan-note/siyuan/blob/9f775e8a12daef8255556097396f9b2739078892/kernel/treenode/table_cell_rich.go#L142-L178","documentation":"While syncing a table cell rich text projection back to its origin node, an inline signature mismatch was found but the expected node has no entry in the sources map, so the kernel cannot locate the origin node to write content back to. This indicates the projection's marker (the mapping from projected node to origin) was lost or altered.","triggerScenarios":"The projected inline node's signature differs from the origin and sources[want] is nil — e.g. the projection markers were stripped by an external edit, or the fragment was regenerated without ProjectTableCellRichWithSources before syncing.","commonSituations":"External tools rewriting table cell HTML/markdown and dropping internal marker attributes; data migrations between document spec versions; custom scripts manipulating .sy files.","solutions":["Re-open and re-render the document so markers are regenerated","Restore the affected block from data history (right-click block - history) or sync snapshots","Avoid editing projected table cell content outside the editor; edit the source code/math block instead","If a plugin caused it, disable the plugin and repair the block"],"exampleFix":"// before: sync without regenerated sources\nsync(expected.FirstChild, cell.FirstChild) // sources map stale\n// after: rebuild projection + sources before sync\nexpected, sources := parse.ProjectTableCellRichWithSources(fragment)","handlingStrategy":"validation","validationCode":"expected, sources := parse.ProjectTableCellRichWithSources(fragment)\nfor n := expected.FirstChild; n != nil; n = n.Next {\n  if sources[n] == nil { reparse() } // marker would be missing\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Always build sources via ProjectTableCellRichWithSources, never a hand-made map","Do not strip marker attributes from projected cells","Restore edited cells from block history instead of patching markers"],"tags":["ast","table","markers"],"backgroundTag":"internal-invariant-violation","analyzedSha":"9f775e8a12daef8255556097396f9b2739078892","analyzedAt":"2026-09-19T03:17:15.984Z","contentChangedAt":"2026-09-19T03:17:15.984Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}