siyuan-note/siyuan · error
get block failed: %s
Error message
get block failed: %s
What it means
First failure mode of buildUpdatedTaskListItemBlockDOM (kernel/api/block_op.go), which backs POST /api/block/updateTaskListItemMarker and its batch variant. The block id passed format validation (InvalidIDPattern) but model.GetBlock failed at the SQL layer; the underlying error text is appended after the prefix, so the real cause (query failure, unavailable/corrupt index) rides along in the message.
Source
Thrown at kernel/api/block_op.go:52
func parseBlockUpdateInput(arg map[string]any, ret *gulu.Result) (input model.BlockUpdateInput, ok bool) {
if !util.ParseJsonArgs(arg, ret,
util.BindJsonArg("id", &input.ID, true, true),
util.BindJsonArg("data", &input.Data, true, false),
util.BindJsonArg("dataType", &input.DataType, true, true),
util.BindJsonArg("lockType", &input.LockType, false, false),
) {
return
}
if util.InvalidIDPattern(input.ID, ret) {
return input, false
}
return input, true
}
func buildUpdatedTaskListItemBlockDOM(id, marker string, luteEngine *lute.Lute) (data string, err error) {
block, err := model.GetBlock(id, nil)
if err != nil {
return "", errors.New("get block failed: " + err.Error())
}
if "NodeListItem" != block.Type {
return "", errors.New("block is not a list item")
}
tree, err := filesys.LoadTree(block.Box, block.Path, luteEngine)
if err != nil {
return "", errors.New("load tree failed: " + err.Error())
}
li := treenode.GetNodeInTree(tree, id)
if li == nil {
return "", errors.New("block not found")
}
if 3 != li.ListData.Typ {
return "", errors.New("block is not a task list item")View on GitHub (pinned to afa823b6b4)
Solutions
- Verify the id first with /api/block/getBlockInfo (or getBlockKramdown) to see whether the block is queryable at all
- Wait for indexing/sync to quiesce (check the status via the kernel UI/status API) and retry the call
- If the block genuinely exists on disk, trigger a rebuild of the content index so the blocks table is repopulated
- Inspect the appended underlying error and the kernel log; if siyuan.db is corrupt, restore the workspace from backup or repo snapshot
Defensive patterns
Strategy: try-catch
Validate before calling
const info = await fetchPost('/api/block/getBlockInfo', { id });
if (info.code !== 0) {
throw new Error(`block [${id}] not queryable, skip marker update`);
}
await fetchPost('/api/block/updateTaskListItemMarker', { id, marker }); Try / catch
try {
await updateTaskMarker(id, marker);
} catch (e) {
if (/^get block failed:/.test(e.message)) {
const cause = e.message.slice('get block failed:'.length).trim();
// index/db level: wait for indexing to settle, verify block exists, then retry once
}
} Prevention
- Validate the block is queryable via getBlockInfo before mutating it
- Avoid calling block APIs during heavy indexing/sync windows
- Log the appended underlying error — it distinguishes missing block from db failure
When it happens
Trigger: Calling /api/block/updateTaskListItemMarker with an id that is well-formed but absent from or broken in the SQL index (siyuan.db); calling while the database is locked by indexing, sync, or another heavy transaction; calling right after workspace corruption or an interrupted reindex.
Common situations: Stale block id captured before a rebuild; kernel mid-reindex or sync so the blocks table is inconsistent; siyuan.db corrupted after a crash or bad shutdown; plugin cached ids across workspace switches.
Understand the failure class
Background: Database query failed: Internal Server Error 500s wrapping SQL, Prisma, and connection failures — what to check first — this error's family across 16 libraries.
Related errors
- block not found
- block is not a list item
- block is not a task list item
- Content block with id [%s] not found
- block updates are empty
AI-assisted analysis of siyuan-note/siyuan@afa823b6b4 (2026-08-18).
Data as JSON: /api/errors/a55cbcc2a40f5a8a.
Report an issue: GitHub.