siyuan-note/siyuan · error

block [ ] is not a document

Error message

block [%s] is not a document

What it means

GetDocBlocksOrders collects the block ordering structure of a document tree, but it first verifies that the given ID actually belongs to the tree's root document block. If the tree loaded for `id` has a root whose ID differs from the requested ID, the kernel rejects the call because only a document (root) ID is valid here, not a child block or arbitrary ID.

Solutions

  1. Pass the document's root ID (tree.Root.ID), not a child block ID — e.g. query `SELECT root_id FROM blocks WHERE id = ?` first
  2. Verify the document still exists and matches the ID (check for sync/renames that changed the root ID)
  3. Trim/validate the ID string for typos or truncation before calling
  4. Handle the error by falling back to resolving the parent document of the block instead of failing

Example fix

// before
orders, err := model.GetDocBlocksOrders(blockID) // blockID may be a child
// after
var rootID string
row := db.QueryRow("SELECT root_id FROM blocks WHERE id = ?", blockID)
row.Scan(&rootID)
orders, err := model.GetDocBlocksOrders(rootID)
Defensive patterns

Strategy: validation

Validate before calling

function isDocID(id string, db *sql.DB) bool {
  var rootID string
  return db.QueryRow("SELECT root_id FROM blocks WHERE id = ?", id).Scan(&rootID) == nil && rootID == id
}

Try / catch

orders, err := model.GetDocBlocksOrders(id)
if err != nil && strings.Contains(err.Error(), "is not a document") {
  // resolve parent document and retry
}

Prevention

When it happens

Trigger: Calling GetDocBlocksOrders (or the API surface that wraps it) with: (1) a child-block ID instead of the document ID; (2) a stale/deleted document ID whose tree resolution falls back to a different root; (3) a mistyped or truncated block ID.

Common situations: Plugins or scripts iterate the SQL blocks table and pass non-root block IDs; code caches document IDs from a previous session that no longer match after re-index or sync; user-supplied IDs from links contain an anchor block ID rather than the doc ID.

Understand the failure class

Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.

Related errors


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

Appendix: source

Thrown at kernel/model/blockinfo.go:596

	for _, id := range ids {
		ret[id] = nodesIndexes[id]
	}
	return
}

func GetDocBlocksOrders(id string) (ret []string, err error) {
	ret = []string{}
	tree, err := LoadTreeByBlockID(id)
	if err != nil {
		return
	}
	if nil == tree || nil == tree.Root {
		err = ErrTreeNotFound
		return
	}
	if tree.Root.ID != id {
		err = fmt.Errorf("block [%s] is not a document", id)
		return
	}

	ret = getDocBlocksOrdersInTree(tree)
	return
}

func getDocBlocksOrdersInTree(tree *parse.Tree) (ret []string) {
	ret = []string{}
	ast.Walk(tree.Root, func(n *ast.Node, entering bool) ast.WalkStatus {
		if !entering || n == tree.Root || !n.IsBlock() || ast.NodeKramdownBlockIAL == n.Type || "" == n.ID {
			return ast.WalkContinue
		}

		ret = append(ret, n.ID)
		return ast.WalkContinue
	})
	return

View on GitHub (pinned to 9f775e8a12)