siyuan-note/siyuan · error
ErrBlockNotFound
ErrBlockNotFound
Error message
block not found
What it means
ErrBlockNotFound is the sentinel for a block that cannot be located — either the block ID does not resolve in the tree/index, or (as in publish-serving paths) access control intentionally reports the block as nonexistent to avoid leaking its existence. Callers compare with errors.Is or match its .Error() string.
Solutions
- Verify the block ID exists via /api/block/getBlockInfo or a SQL query (blocks table) before use
- If this is a publish instance, enable publish access for the block/doc or access it from the authenticated kernel instead
- Clean up stale references (attribute view bindings, links) pointing to deleted blocks
- Return/handle the sentinel explicitly so clients get a stable 'block not found' signal rather than a generic error
Example fix
// before
ret.Msg = "block missing"
// after
if !model.CheckBlockIdMetadataAccessableByPublishAccessInBox(c, publishAccess, id, notebook) {
ret.Code = -1
ret.Msg = model.ErrBlockNotFound.Error()
return contractFailure[string](ret)
} Defensive patterns
Strategy: validation
Validate before calling
// TypeScript: confirm the block exists before dependent calls
const info = await fetchPost('/api/block/getBlockInfo', { id });
if (info.code !== 0) throw new Error('block missing: ' + id); Type guard
function isBlockNotFound(msg: string | null | undefined): boolean {
return msg === 'block not found';
} Try / catch
// Go
if errors.Is(err, model.ErrBlockNotFound) {
// treat as missing (or hidden on publish instances) rather than a crash
return apicontract.Success(model.ErrBlockNotFound.Error())
} Prevention
- Validate block IDs against the blocks table before writing bindings or links
- On publish instances, configure publish access for blocks clients need to reach
- Prune stale references after deleting docs; run tree cleanup so attribute views don't point at removed blocks
When it happens
Trigger: Publish/publish-access checks (kernel/api/block.go:488, kernel/api/filetree.go:333) return ErrBlockNotFound.Error() when isBlockPublishAccessible / CheckBlockIdMetadataAccessableByPublishAccessInBox denies access; also returned by binding validators (preflightAttributeViewCellBindings, validateAttributeViewBinding) and contract getters when the block ID is absent.
Common situations: Requesting a block ID that was deleted or whose doc was removed; accessing unpublished blocks through the publish server; stale IDs saved in attribute views or plugins after docs were restructured; ID case/whitespace mistakes.
Understand the failure class
Background: "Not found" and "does not exist" errors: why "Task not found", "No such folder", and "Can't find" fire when a lookup comes back empty — this error's family across 14 libraries.
Related errors
- boot appearance not found
- ErrBoxNotFound
- ErrTreeNotFound
- source document [ ] not found
- target document [ ] not found
AI-assisted analysis of siyuan-note/siyuan@9f775e8a12 (2026-09-19).
Data as JSON: /api/errors/dc43f913058ecb0a.
Report an issue: GitHub.
Appendix: 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 9f775e8a12)