siyuan-note/siyuan · error
ErrTreeNotFound
ErrTreeNotFound
Error message
tree not found
What it means
ErrTreeNotFound is the sentinel returned when the document tree (.sy) for a block/doc ID cannot be loaded — the document file is missing from the notebook. API handlers special-case it to show localized 'doc not found' messages (Conf.Language(15)) instead of dumping the raw error.
Solutions
- Confirm the doc ID exists (query blocks table or list files under data/<box>/) and fix stale references
- Sync the workspace so missing docs are restored or removed references converge
- Map errors.Is(err, model.ErrTreeNotFound) to the localized message (Conf.Language(15)) in handlers rather than generic error text
- Reindex the notebook if data files exist but the index is stale (though typically the file is genuinely gone)
Example fix
// before
ret.Msg = err.Error()
// after
case errors.Is(err, model.ErrTreeNotFound):
ret.Msg = fmt.Sprintf(model.Conf.Language(15), id)
default:
ret.Msg = err.Error() Defensive patterns
Strategy: fallback
Validate before calling
// TypeScript: check the doc path resolves before loading by ID
const p = await fetchPost('/api/filetree/getHPathByID', { id });
if (p.code !== 0) throw new Error('doc missing: ' + id); Type guard
function isTreeNotFound(msg: string | null | undefined): boolean {
return msg === 'tree not found';
} Try / catch
// Go
case errors.Is(err, model.ErrTreeNotFound):
ret.Msg = fmt.Sprintf(model.Conf.Language(15), id)
default:
ret.Msg = err.Error() Prevention
- Verify doc IDs exist before opening old links or resuming saved state
- Complete sync before relying on cross-device document references
- Restore missing .sy files from backup/sync if data was deleted manually
When it happens
Trigger: getDoc/getBlockInfo paths (kernel/api/block.go:762) load a tree by block or doc ID and the .sy file does not exist; contract getters (getHPathByIDContract, getPathByIDContract, getFullHPathByIDContract) and export preflight (prepareExportAssets) propagate it; LoadTreeByBlockIDWithReindex fails to find the doc.
Common situations: Doc deleted on another device and sync removed the .sy while an old link/ID is still requested; stale browser tab holding a removed doc ID; corrupted or manually deleted data/ folder contents; export of a doc that no longer exists.
Understand the failure class
Background: "File not found" and ENOENT errors: why libraries can't find a file that should exist — this error's family across 50 libraries.
Related errors
- boot appearance not found
- ErrBlockNotFound
- ErrBoxNotFound
- source document [ ] not found
- target document [ ] not found
AI-assisted analysis of siyuan-note/siyuan@9f775e8a12 (2026-09-19).
Data as JSON: /api/errors/4562081f91cefdb5.
Report an issue: GitHub.
Appendix: source
Thrown at kernel/model/tree.go:213
}
}
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)
if nil == bt && "" == boxID {View on GitHub (pinned to 9f775e8a12)