{"record":{"id":"befc4e4b5f8c4024","repo":"siyuan-note/siyuan","slug":"found-invalid-id-s","errorCode":null,"errorMessage":"found invalid ID [%s]","messagePattern":"found invalid ID \\[(.+?)\\]","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"kernel/model/block_update.go","lineNumber":198,"sourceCode":"\t\tblankParagraph := treenode.NewParagraph(\"\")\n\t\tret = luteEngine.RenderNodeBlockDOM(blankParagraph)\n\t}\n\n\tinvalidID := \"\"\n\tif nil != tree && nil != tree.Root {\n\t\tast.Walk(tree.Root, func(n *ast.Node, entering bool) ast.WalkStatus {\n\t\t\tif !entering {\n\t\t\t\treturn ast.WalkContinue\n\t\t\t}\n\t\t\tif \"\" != n.ID && !ast.IsNodeIDPattern(n.ID) {\n\t\t\t\tinvalidID = n.ID\n\t\t\t\treturn ast.WalkStop\n\t\t\t}\n\t\t\treturn ast.WalkContinue\n\t\t})\n\t}\n\tif \"\" != invalidID {\n\t\treturn \"\", errors.New(\"found invalid ID [\" + invalidID + \"]\")\n\t}\n\treturn\n}\n\nfunc parseBlockUpdateData(data, dataType string, luteEngine *lute.Lute) (ret string, tree *parse.Tree, err error) {\n\tret = data\n\tswitch dataType {\n\tcase \"markdown\":\n\t\tret, err = DataBlockDOM(data, luteEngine)\n\t\tif err != nil {\n\t\t\terr = fmt.Errorf(\"data block DOM failed: %w\", err)\n\t\t\treturn\n\t\t}\n\tcase \"dom\":\n\tdefault:\n\t\terr = fmt.Errorf(\"unsupported block data type [%s]\", dataType)\n\t\treturn\n\t}","sourceCodeStart":180,"sourceCodeEnd":216,"githubUrl":"https://github.com/siyuan-note/siyuan/blob/8641553a1f07374001902d3ce773285db1292b2d/kernel/model/block_update.go#L180-L216","documentation":"DataBlockDOM converts markdown block-update data into SiYuan block DOM. While walking the produced tree it validates every node ID; any node carrying an ID that is not a well-formed block ID sets invalidID, and the function returns this error instead of producing DOM. It guards against markdown pasted with foreign or corrupted {{select}} / {: id=\"...\"} attributes.","triggerScenarios":"Calling parseBlockUpdateData with dataType=\"markdown\" where the markdown text embeds custom node-ID attributes that fail ID validation — e.g. manually authored {: id=\"123\"} attributes, IDs copied from another workspace with different node-id format, or truncated/corrupted IDs.","commonSituations":"Pasting markdown exported from other tools (Notion, Obsidian) that carries id-like attributes; hand-edited .sy content or programmatically generated markdown with fake IDs; migration of content between SiYuan instances with modified ID schemes.","solutions":["Strip or regenerate ID attributes in the markdown before sending (send plain markdown without {: id=...})","Only reuse IDs that were obtained from SiYuan itself (SQL blocks table / getBlockKramdown)","Use dataType=\"dom\" with valid, round-tripped block DOM instead of hand-crafted markdown","Sanitize imported markdown with a regex removing invalid IAL id attributes prior to the call"],"exampleFix":"// before\nconst md = 'Paragraph text {: id=\"bad-id!!\"}';\nawait updateBlock(id, 'markdown', md);\n// after\nconst md = 'Paragraph text'; // let SiYuan generate a fresh valid ID\nawait updateBlock(id, 'markdown', md);","handlingStrategy":"validation","validationCode":"function hasValidBlockIDs(markdown) {\n  const ials = markdown.matchAll(/\\{:\\s*id=\"([^\"]+)\"/g);\n  for (const m of ials) {\n    if (!/^[0-9]{14}-[0-9a-z]{7}$/.test(m[1])) return false;\n  }\n  return true;\n}","typeGuard":null,"tryCatchPattern":"try {\n  await updateBlock(id, 'markdown', md);\n} catch (e) {\n  if (String(e.msg || e).includes('invalid ID')) {\n    const cleaned = md.replace(/\\s*\\{:\\s*id=\"[^\"]*\"\\}/g, '');\n    await updateBlock(id, 'markdown', cleaned);\n  } else { throw e; }\n}","preventionTips":["Never hand-write {: id=...} IAL attributes; let SiYuan generate them","Strip foreign id-like attributes when importing markdown from other tools","Only reuse IDs read from SiYuan's own exports"],"tags":["block-update","id-validation","markdown","kernel"],"backgroundTag":"invalid-identifier-format","analyzedSha":"8641553a1f07374001902d3ce773285db1292b2d","analyzedAt":"2026-09-11T16:08:28.414Z","contentChangedAt":"2026-09-11T16:08:28.414Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}