siyuan-note/siyuan · error

block not found

Error message

block not found

What it means

SiYuan's task-list-item update API resolves the block by ID within its loaded document tree via treenode.GetNodeInTree. Although model.GetBlock succeeded earlier in buildUpdatedTaskListItemBlockDOM, the node cannot be located in the freshly parsed AST, so the function aborts with "block not found". This indicates the SQL index and the on-disk .sy tree are out of sync, or the tree changed between the two lookups.

Solutions

  1. Verify the block still exists with /api/filetree/getDoc (or /api/query/sql SELECT * FROM blocks WHERE id='...'), then re-fetch a fresh ID before retrying the marker update
  2. Rebuild the index (Settings - About - Rebuild index, or /api/system/reindex) if the blocks table and .sy files disagree
  3. Confirm the document containing the block was not deleted/moved by a concurrent client or sync; re-open the doc to get current IDs
  4. Re-run the update in a retry after a short delay if a sync/index queue was mid-flight

Example fix

// before: cached id may be stale
await fetchPost('/api/block/updateTaskListItemMarker', { id: cachedId, marker: 'x' });
// after: re-resolve the id from a fresh SQL query first
const rows = await fetchPost('/api/query/sql', { stmt: "SELECT id FROM blocks WHERE content='TODO' AND type='l' LIMIT 1" });
await fetchPost('/api/block/updateTaskListItemMarker', { id: rows[0].id, marker: 'x' });
Defensive patterns

Strategy: validation

Validate before calling

const rows = await fetchPost('/api/query/sql', { stmt: `SELECT id FROM blocks WHERE id='${id}'` });
if (!rows.length) throw new Error(`block ${id} no longer exists; re-resolve its ID`);

Type guard

const blockExists = (rows) => Array.isArray(rows) && rows.length > 0 && typeof rows[0].id === 'string';

Try / catch

try {
  await fetchPost('/api/block/updateTaskListItemMarker', { id, marker });
} catch (e) {
  if (e?.msg === 'block not found') {
    const fresh = await sql("SELECT id FROM blocks WHERE type='l' AND subtype='t' LIMIT 1");
    if (fresh.length) return retryWith(fresh[0].id);
  }
  throw e;
}

Prevention

When it happens

Trigger: Calling POST /api/block/updateTaskListItemMarker (or batchUpdateTaskListItemMarker) with an ID that exists in the block index (blocks table) but not in the parsed tree: a stale/deleted block ID, an ID whose document was just deleted or renamed, or an index that has not caught up after a sync.

Common situations: Scripts or plugins caching block IDs that were deleted; a sync operation replaced the document; the blocks SQLite index is stale relative to the .sy files on disk; passing an ID from another notebook or an old history snapshot.

Understand the failure class

Background: Record Not Found Errors: "not found", RecordNotFound, and "was not found" — what they mean and how to fix them — this error's family across 28 libraries.

Related errors


AI-assisted analysis of siyuan-note/siyuan@9f775e8a12 (2026-09-19). Data as JSON: /api/errors/07f4fc6f49446008. Report an issue: GitHub.

Appendix: source

Thrown at kernel/api/block_op.go:51

func buildUpdatedTaskListItemBlockDOM(id, marker string, luteEngine *lute.Lute) (data string, err error) {
	block, err := model.GetBlock(id, nil)
	if err != nil {
		return "", errors.New("get block failed: " + err.Error())
	}

	if "NodeListItem" != block.Type {
		return "", errors.New("block is not a list item")
	}

	tree, err := filesys.LoadTree(block.Box, block.Path, luteEngine)
	if err != nil {
		return "", errors.New("load tree failed: " + err.Error())
	}

	li := treenode.GetNodeInTree(tree, id)
	if li == nil {
		return "", errors.New("block not found")
	}

	if 3 != li.ListData.Typ {
		return "", errors.New("block is not a task list item")
	}

	if 1 != len(marker) {
		return "", errors.New("task list item marker length should be 1")
	}

	liMarker := marker[0]
	if '[' == liMarker || ']' == liMarker {
		return "", errors.New("task list item marker can not be [ or ]")
	}

	markerNode := li.ChildByType(ast.NodeTaskListItemMarker)
	if nil == markerNode {
		return "", errors.New("task list item marker not found")

View on GitHub (pinned to 9f775e8a12)