{"record":{"id":"9e7b3adf56a489cb","repo":"siyuan-note/siyuan","slug":"conf-language-15-formatted-with-block-id-localiz","errorCode":null,"errorMessage":"Conf.Language(15) formatted with block id (localized block-not-found message)","messagePattern":"Conf\\.Language\\(15\\) formatted with block id \\(localized block-not-found message\\)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"kernel/model/blockial.go","lineNumber":100,"sourceCode":"\tif \"0\" != timed {\n\t\tt, e := dateparse.ParseIn(timed, time.Now().Location())\n\t\tif nil != e {\n\t\t\treturn e\n\t\t}\n\t\ttimedMills = t.UnixMilli()\n\t}\n\n\tFlushTxQueue()\n\n\tattrs := sql.GetBlockAttrs(id)\n\ttree, err := LoadTreeByBlockID(id)\n\tif err != nil {\n\t\treturn\n\t}\n\n\tnode := treenode.GetNodeInTree(tree, id)\n\tif nil == node {\n\t\treturn fmt.Errorf(Conf.Language(15), id)\n\t}\n\n\tif ast.NodeDocument != node.Type && node.IsContainerBlock() {\n\t\tnode = treenode.FirstLeafBlock(node)\n\t}\n\n\tcontent := sql.NodeStaticContent(node, nil, false, false, false)\n\tcontent = gulu.Str.SubStr(content, 128)\n\tcontent = strings.ReplaceAll(content, editor.Zwsp, \"\")\n\terr = SetCloudBlockReminder(id, content, timedMills)\n\tif err != nil {\n\t\treturn\n\t}\n\n\tattrName := \"custom-reminder-wechat\"\n\tif \"0\" == timed {\n\t\tdelete(attrs, attrName)\n\t\told := node.IALAttr(attrName)","sourceCodeStart":82,"sourceCodeEnd":118,"githubUrl":"https://github.com/siyuan-note/siyuan/blob/8641553a1f07374001902d3ce773285db1292b2d/kernel/model/blockial.go#L82-L118","documentation":"After locating the tree for the given block id, SetBlockReminder calls treenode.GetNodeInTree and throws this error when no node with that id exists in the tree. The message is the localized block-not-found template (key 15) with the offending id interpolated, so the user sees which block was not found.","triggerScenarios":"Calling SetBlockReminder with an id that does not resolve to a node in the loaded tree: deleted block, mistyped id, id from a different notebook, or tree load failure swallowed by the earlier error return.","commonSituations":"Frontend holds a stale block id after the block was deleted or the doc re-indexed; API scripts using hand-copied ids; reminders set on a block in a closed/unloaded notebook.","solutions":["Re-fetch the block id (e.g. via /api/filetree/getDoc) and retry with a valid id","Verify the block still exists — if deleted, recreate it before setting a reminder","Confirm the id belongs to a notebook currently present in the workspace (not renamed/deleted box)"],"exampleFix":"// before\nSetBlockReminder(\"dead-id\", \"2024-06-01 09:00\") // Conf.Language(15) formatted with \"dead-id\"\n// after\nnode := treenode.GetNodeInTree(tree, \"20240101120000-abc\")\nif node != nil { SetBlockReminder(\"20240101120000-abc\", \"2024-06-01 09:00\") }","handlingStrategy":"validation","validationCode":"// Go: verify the node exists before setting a reminder\nif tree, err := model.LoadTree(box, path); err == nil {\n    if treenode.GetNodeInTree(tree, id) == nil {\n        return errors.New(\"block not found: \" + id)\n    }\n}\n// TS: fetch block info first\nconst info = await fetchPost(\"/api/block/getBlockInfo\", { id });\nif (!info.code === 0) throw new Error(\"block missing\");","typeGuard":"func blockExists(box, path, id string) bool {\n    tree, err := model.LoadTree(box, path)\n    return err == nil && treenode.GetNodeInTree(tree, id) != nil\n}","tryCatchPattern":null,"preventionTips":["Refresh block ids after any delete/move operation instead of caching them","Validate ids with getBlockInfo before reminder calls","Use real SiYuan block ids (YYYYMMDDhhmmss-hex), not hand-made values"],"tags":["block-not-found","stale-id"],"backgroundTag":"resource-not-found","analyzedSha":"8641553a1f07374001902d3ce773285db1292b2d","analyzedAt":"2026-09-11T16:08:28.414Z","contentChangedAt":"2026-09-11T16:08:28.414Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}