siyuan-note/siyuan · error

Content block with id

Error message

Content block with id [%s] not found

What it means

kernel/model/blockial.go:100, from SetBlockReminder (language key 15): the block's document loaded successfully via LoadTreeByBlockID, but treenode.GetNodeInTree found no node with that ID inside it. The reminder operation aborts before any attribute is written. Practically: the ID is stale (block deleted/merged since you learned it) or the block index mapped the ID to a document that no longer contains it.

Solutions

  1. Re-resolve the ID immediately before the call: /api/query select id from blocks where id='...'.
  2. If it should exist, rebuild the index (Settings - Search - rebuild index) to fix stale blocktree.db mappings.
  3. Check File - History / recycle bin if the deletion was accidental.
Defensive patterns

Strategy: validation

Validate before calling

// Verify the block still exists before updating
const q = await fetch("/api/query", {
  method: "POST",
  headers: { "Content-Type": "application/json" },
  body: JSON.stringify({ stmt: `select id, type, root_id from blocks where id='${blockID}'` }),
});
const qr = await q.json();
if (!qr.data?.length) throw new Error(`Block ${blockID} no longer exists`);

Type guard

async function reminderTargetExists(id: string): Promise<boolean> {
  const r = await fetch("/api/query", { method: "POST",
    headers: { "Content-Type": "application/json" },
    body: JSON.stringify({ stmt: `select id from blocks where id='${id}'` }) });
  const j = await r.json();
  return j.code === 0 && (j.data?.length ?? 0) > 0;
}

Try / catch

try {
  await setBlockReminder(id, timed);
} catch (e) {
  if (/Content block with id \[.*\] not found/.test(e.message)) {
    const fresh = await resolveBlockByText(anchorText); // re-discover target
    if (fresh) await setBlockReminder(fresh, timed);
  } else throw e;
}

Prevention

When it happens

Trigger: POST /api/attr/setBlockReminder with an ID from an old query/cached list after the block was deleted or its document restructured; racing with sync deletions; well-formed ID belonging to a block in another document due to index staleness.

Common situations: Reminder scripts iterating saved block IDs; schedules computed offline then applied after the user edited/deleted blocks; multi-client sync removing blocks between query and write.

Related errors


AI-assisted analysis of siyuan-note/siyuan@afa823b6b4 (2026-08-18). Data as JSON: /api/errors/f43c88662159b5d4. Report an issue: GitHub.

Appendix: 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 afa823b6b4)