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

  1. 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
  2. Re-run index rebuild (Rebuild Index) if the block exists in the .sy file but the index is stale
  3. Re-create the deleted block or fix the referencing link/database row to point to an existing ID
  4. 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

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.