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

  1. 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.
  2. If stale broadly, run /api/system/uiproc (reload UI) or trigger a reindex via /api/filetree/upsertIndexes / reindex so the blocktree matches disk.
  3. 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

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.