{"record":{"id":"0337c3f38a342a0b","repo":"siyuan-note/siyuan","slug":"found-invalid-id-invalidid","errorCode":null,"errorMessage":"found invalid ID [\" + invalidID + \"]","messagePattern":"found invalid ID \\[\" \\+ invalidID \\+ \"\\]","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/9f775e8a12daef8255556097396f9b2739078892/kernel/model/block_update.go#L180-L216","documentation":"DataBlockDOM converts a Markdown string to block DOM for the block-update API and validates that every node ID found in the produced tree matches SiYuan's block ID pattern (a 14-character timestamp-based string). If any node carries an explicit ID that does not match the expected pattern, conversion is aborted and this error is returned with the offending ID embedded in the message. It prevents malformed custom IDs from entering the document tree via /api/block/updateBlock or insert.","triggerScenarios":"Calling DataBlockDOM (or the updateBlock API with dataType \"markdown\") with markdown containing kramdown-style explicit block IDs like {: id=\"custom-id\"} or {: id=\"123\"} that are not valid SiYuan IDs (must match the IsNodeIDPattern 14-digit format). The walk stops at the first offending node and reports its ID.","commonSituations":"Pasting markdown exported from other tools (Logseq, Notion, Obsidian) that embed their own anchor/ID attributes; hand-writing {: id=\"...\"} attributes with arbitrary slugs; programmatically generated markdown reusing foreign identifiers.","solutions":["Remove or correct the invalid {: id=\"...\"} attribute in the markdown payload so all IDs match SiYuan's 14-character ID pattern","Let SiYuan generate IDs itself: strip explicit id attributes from the markdown before sending","Sanitize the payload client-side with the same pattern regex used by ast.IsNodeIDPattern before calling the API"],"exampleFix":"// before\nmarkdown := \"## Heading {: id=\\\"my-slug\\\"}\"\n// after\nmarkdown := \"## Heading\" // or use a valid 14-char ID: {: id=\"20240101120000-abc1234\"}","handlingStrategy":"validation","validationCode":"function hasValidBlockIds(markdown) {\n  return !Array.from(markdown.matchAll(/\\{:\\s*id=\"([^\"]+)\"\\}/g))\n    .some(([, id]) => !/^\\d{14}-[0-9a-z]{7}$/.test(id));\n}\nif (!hasValidBlockIds(payload.data)) throw new Error(\"payload contains invalid block IDs\");","typeGuard":"const isValidSiYuanId = (id) => typeof id === \"string\" && /^\\d{14}-[0-9a-z]{7}$/.test(id);","tryCatchPattern":null,"preventionTips":["Strip explicit {: id=\"...\"} attributes from external markdown before API calls","Regenerate IDs with SiYuan instead of importing foreign identifiers","Add a pre-send regex validation of any hand-crafted block IDs"],"tags":["validation","block-id","markdown","api"],"backgroundTag":"invalid-identifier-format","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"}