siyuan-note/siyuan · error
Content block with id [%s] not found
Error message
Content block with id [%s] not found
What it means
In SetBlockReminder, after FlushTxQueue + LoadTreeByBlockID(id) succeeds, treenode.GetNodeInTree(tree, id) returns nil and the function returns fmt.Errorf(Conf.Language(15), id) — 'Content block with id [%s] not found'. This means the blocktree (blocktree.db) has a row for the id, but the node is absent from the loaded .sy tree: the in-memory/SQLite index and the on-disk tree are out of sync. It is distinct from LoadTreeByBlockID failing outright (which returns a different error earlier at blockial.go:94).
Source
Thrown at kernel/model/blockial.go:100
if "0" != timed {
t, e := dateparse.ParseIn(timed, time.Now().Location())
if nil != e {
return e
}
timedMills = t.UnixMilli()
}
FlushTxQueue()
attrs := sql.GetBlockAttrs(id)
tree, err := LoadTreeByBlockID(id)
if err != nil {
return
}
node := treenode.GetNodeInTree(tree, id)
if nil == node {
return fmt.Errorf(Conf.Language(15), id)
}
if ast.NodeDocument != node.Type && node.IsContainerBlock() {
node = treenode.FirstLeafBlock(node)
}
content := sql.NodeStaticContent(node, nil, false, false, false)
content = gulu.Str.SubStr(content, 128)
content = strings.ReplaceAll(content, editor.Zwsp, "")
err = SetCloudBlockReminder(id, content, timedMills)
if err != nil {
return
}
attrName := "custom-reminder-wechat"
if "0" == timed {
delete(attrs, attrName)
old := node.IALAttr(attrName)View on GitHub (pinned to 251596fc0d)
Solutions
- Re-resolve the id: call /api/block/getBlockInfo or /api/block/getDocInfo with the id and confirm it is still live before setting a reminder.
- If stale broadly, run /api/system/uiproc (reload UI) or trigger a reindex via /api/filetree/upsertIndexes / reindex so the blocktree matches disk.
- If the block was legitimately deleted, stop referencing the id and obtain the current equivalent block id.
Example fix
// before
err := model.SetBlockReminder(id, timed)
// after: confirm the node is actually in the tree before calling
tree, _ := model.LoadTreeByBlockID(id)
if tree == nil || treenode.GetNodeInTree(tree, id) == nil {
return fmt.Errorf(Conf.Language(15), id)
}
err := model.SetBlockReminder(id, timed) Defensive patterns
Strategy: validation
Validate before calling
// Confirm the node is present in its loaded tree before setting the reminder.
tree, err := model.LoadTreeByBlockID(id)
if err != nil || tree == nil || treenode.GetNodeInTree(tree, id) == nil {
return fmt.Errorf(model.Conf.Language(15), id)
} Try / catch
// HTTP caller: treat Language(15) / 'not found' as stale-id and re-resolve.
const r = await fetchSyncPost('/api/block/setBlockReminder', {id, timed})
if (r.code === -1 && r.msg.includes('not found')) {
const fresh = await refetchBlockId(id)
if (fresh) await fetchSyncPost('/api/block/setBlockReminder', {id: fresh, timed})
} Prevention
- Never cache block ids across sync/reload cycles; re-query before mutating.
- Trigger a notebook reindex when 'not found' errors appear for ids that should exist.
- Avoid scheduling reminders against ids of blocks that are candidates for deletion.
When it happens
Trigger: POST /api/block/setBlockReminder with an id whose blocktree entry references a tree that no longer contains the node — e.g. the node was removed by another client and not yet re-indexed, a data-repo reset left a stale blocktree, manual edits to .sy files, or a partially-completed sync.
Common situations: Holding a block id across a sync/reload cycle; using an id copied from an older document snapshot; index corruption after an unclean shutdown; referencing a block that was just deleted in the same transaction but the caller still has its id.
AI-assisted analysis of siyuan-note/siyuan@251596fc0d (2026-08-12).
Data as JSON: /api/errors/f43c88662159b5d4.
Report an issue: GitHub.