siyuan-note/siyuan · error
ErrBlockNotFound
ErrBlockNotFound
Error message
block not found
What it means
ErrBlockNotFound is the sentinel error meaning no block with the given ID exists (in the tree or index). Model functions like getRefText, getDoc, getHPathByPath and attribute-view item creation return it; API handlers also use its text directly as a generic 'block not found' response when publish access checks fail.
Source
Thrown at kernel/model/tree.go:212
return
}
}
if err = treenode.CheckSpecJSON(data); nil != err {
return
}
ret, err = dataparser.ParseJSONWithoutFix(data, luteEngine.ParseOptions)
if err != nil {
logging.LogErrorf("parse json to tree [%s] failed: %s", localPath, err)
return
}
return
}
var (
ErrBoxNotFound = errors.New("notebook not found")
ErrBoxClosed = errors.New("notebook closed")
ErrBlockNotFound = errors.New("block not found")
ErrTreeNotFound = errors.New("tree not found")
ErrIndexing = errors.New("indexing")
ErrBoxUnindexed = errors.New("notebook unindexed")
ErrInvalidID = errors.New("invalid id")
)
func LoadTreeByBlockIDWithReindex(id string) (ret *parse.Tree, err error) {
return LoadTreeByBlockIDWithReindexInBox(id, "")
}
// LoadTreeByBlockIDWithReindexInBox 与 LoadTreeByBlockIDWithReindex 一致,但按 boxID 路由 blocktree 查询。
func LoadTreeByBlockIDWithReindexInBox(id, boxID string) (ret *parse.Tree, err error) {
if "" == id {
logging.LogWarnf("block id is empty")
return nil, ErrTreeNotFound
}
bt := treenode.GetBlockTreeInBox(id, boxID)View on GitHub (pinned to 8641553a1f)
Solutions
- Verify the block ID exists via /api/filetree/getDocInfo or a SQL query on blocks; refresh the client's references if the block was deleted
- Re-run index rebuild (Rebuild Index) if the block exists in the .sy file but the index is stale
- Re-create the deleted block or fix the referencing link/database row to point to an existing ID
- Treat the error in callers with errors.Is(err, model.ErrBlockNotFound) and show a user-facing 'block does not exist' message
Defensive patterns
Strategy: try-catch
Validate before calling
stmt := database.Query("SELECT id FROM blocks WHERE id = ?", blockID)
if len(stmt) == 0 { return fmt.Errorf("block %s does not exist", blockID) } Try / catch
if errors.Is(err, model.ErrBlockNotFound) {
// show 'block does not exist', refresh references
return
} Prevention
- Verify block IDs exist before linking or adding database rows
- Refresh caches after sync to drop deleted block IDs
- Never assume a pasted/bookmarked block ID is still valid
When it happens
Trigger: Requesting doc info, ref text, or hpath by a block ID that was deleted or never existed; CreateAttributeViewItemDocs with a blockID whose block is gone; publish-access check failing for a block, where the API deliberately returns ErrBlockNotFound.Error() to avoid leaking existence.
Common situations: Stale client cache holding IDs of deleted blocks; pasted links to blocks removed by a sync conflict; plugin querying a block ID from an outdated bookmark; privacy protection returning 'not found' for blocks the requester may not read.
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@8641553a1f (2026-09-11).
Data as JSON: /api/errors/dc43f913058ecb0a.
Report an issue: GitHub.