{"record":{"id":"dc43f913058ecb0a","repo":"siyuan-note/siyuan","slug":"errblocknotfound","errorCode":"ErrBlockNotFound","errorMessage":"block not found","messagePattern":"block not found","errorType":"error_code","errorClass":null,"httpStatus":null,"severity":"error","filePath":"kernel/model/tree.go","lineNumber":212,"sourceCode":"\t\t\treturn\n\t\t}\n\t}\n\n\tif err = treenode.CheckSpecJSON(data); nil != err {\n\t\treturn\n\t}\n\tret, err = dataparser.ParseJSONWithoutFix(data, luteEngine.ParseOptions)\n\tif err != nil {\n\t\tlogging.LogErrorf(\"parse json to tree [%s] failed: %s\", localPath, err)\n\t\treturn\n\t}\n\treturn\n}\n\nvar (\n\tErrBoxNotFound   = errors.New(\"notebook not found\")\n\tErrBoxClosed     = errors.New(\"notebook closed\")\n\tErrBlockNotFound = errors.New(\"block not found\")\n\tErrTreeNotFound  = errors.New(\"tree not found\")\n\tErrIndexing      = errors.New(\"indexing\")\n\tErrBoxUnindexed  = errors.New(\"notebook unindexed\")\n\tErrInvalidID     = errors.New(\"invalid id\")\n)\n\nfunc LoadTreeByBlockIDWithReindex(id string) (ret *parse.Tree, err error) {\n\treturn LoadTreeByBlockIDWithReindexInBox(id, \"\")\n}\n\n// LoadTreeByBlockIDWithReindexInBox 与 LoadTreeByBlockIDWithReindex 一致，但按 boxID 路由 blocktree 查询。\nfunc LoadTreeByBlockIDWithReindexInBox(id, boxID string) (ret *parse.Tree, err error) {\n\tif \"\" == id {\n\t\tlogging.LogWarnf(\"block id is empty\")\n\t\treturn nil, ErrTreeNotFound\n\t}\n\n\tbt := treenode.GetBlockTreeInBox(id, boxID)","sourceCodeStart":194,"sourceCodeEnd":230,"githubUrl":"https://github.com/siyuan-note/siyuan/blob/9f775e8a12daef8255556097396f9b2739078892/kernel/model/tree.go#L194-L230","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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"],"exampleFix":"// before\nret.Msg = \"block missing\"\n\n// after\nif !model.CheckBlockIdMetadataAccessableByPublishAccessInBox(c, publishAccess, id, notebook) {\n    ret.Code = -1\n    ret.Msg = model.ErrBlockNotFound.Error()\n    return contractFailure[string](ret)\n}","handlingStrategy":"validation","validationCode":"// TypeScript: confirm the block exists before dependent calls\nconst info = await fetchPost('/api/block/getBlockInfo', { id });\nif (info.code !== 0) throw new Error('block missing: ' + id);","typeGuard":"function isBlockNotFound(msg: string | null | undefined): boolean {\n  return msg === 'block not found';\n}","tryCatchPattern":"// Go\nif errors.Is(err, model.ErrBlockNotFound) {\n    // treat as missing (or hidden on publish instances) rather than a crash\n    return apicontract.Success(model.ErrBlockNotFound.Error())\n}","preventionTips":["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"],"tags":["go","kernel","block","not-found","publish"],"backgroundTag":"entity-not-found","analyzedSha":"9f775e8a12daef8255556097396f9b2739078892","analyzedAt":"2026-09-19T03:17:15.984Z","contentChangedAt":"2026-09-19T03:17:15.984Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}