siyuan-note/siyuan · error

not query embed block

Error message

not query embed block

What it means

UpdateEmbedBlock updates the content of a query embed block (^(...) block). The library fetches the block tree for the given block ID and verifies that the block's type is actually a block-query-embed node; if the ID points to any other node type (paragraph, heading, etc.), it refuses with "not query embed block". This guards against writing embed-block content onto a normal block.

Solutions

  1. Verify the block ID actually refers to a query embed block (its .sy node type is NodeBlockQueryEmbed) before calling UpdateEmbedBlock
  2. Re-fetch the block via the block tree / SQL to confirm its current type; the ID may point to a block whose type changed after edits
  3. If you intend to update a normal block, use the block update API instead of the embed-block one

Example fix

// before
model.UpdateEmbedBlock(paraBlockID, content) // id is a paragraph block
// after
bt := treenode.GetBlockTree(blockID)
if bt != nil && treenode.TypeAbbr(ast.NodeBlockQueryEmbed.String()) == bt.Type {
    model.UpdateEmbedBlock(blockID, content)
}
Defensive patterns

Strategy: validation

Validate before calling

const bt = GetBlockTree(blockID)
if (!bt || bt.type !== 'query_embed') throw new Error('block is not a query embed block')
await api.updateEmbedBlock(blockID, content)

Type guard

function isQueryEmbedBlock(bt) { return bt != null && bt.type === 'query_embed' }

Try / catch

try { await api.updateEmbedBlock(id, content) } catch (e) { if (String(e).includes('not query embed block')) skipNonEmbed(id); else throw e }

Prevention

When it happens

Trigger: Calling UpdateEmbedBlock with an id whose block tree record has a type other than treenode.TypeAbbr(ast.NodeBlockQueryEmbed.String()) — e.g. passing a regular paragraph or heading block ID — produces this error immediately after the ErrBlockNotFound check passes.

Common situations: Frontend passes the wrong block ID when refreshing embed blocks (e.g. the containing block instead of the embed block itself); stale block IDs after a document was edited so the node changed type; plugins calling the embed-block update API with arbitrary block IDs.

Understand the failure class

Background: "is not a compatible type" / "cannot merge" errors: when a value's type doesn't match what the library requires — this error's family across 65 libraries.

Related errors


AI-assisted analysis of siyuan-note/siyuan@9f775e8a12 (2026-09-19). Data as JSON: /api/errors/888a9bbbb151d0fc. Report an issue: GitHub.

Appendix: source

Thrown at kernel/model/search.go:213

	pageCount = (matchedBlockCount + pageSize - 1) / pageSize
	return
}

type EmbedBlock struct {
	Block               *Block       `json:"block"`
	BlockPaths          []*BlockPath `json:"blockPaths"`
	AllowChildOperation bool         `json:"allowChildOperation"`
}

func UpdateEmbedBlock(id, content string) (err error) {
	bt := treenode.GetBlockTree(id)
	if nil == bt {
		err = ErrBlockNotFound
		return
	}

	if treenode.TypeAbbr(ast.NodeBlockQueryEmbed.String()) != bt.Type {
		err = errors.New("not query embed block")
		return
	}

	embedBlock := &EmbedBlock{
		Block: &Block{
			Markdown: content,
		},
	}

	updateEmbedBlockContent(id, []*EmbedBlock{embedBlock}, bt.BoxID)
	return
}

func GetEmbedBlock(embedBlockID string, includeIDs []string, headingMode int, breadcrumb bool) (ret []*EmbedBlock) {
	return getEmbedBlock(embedBlockID, includeIDs, headingMode, breadcrumb, true, "")
}

func GetEmbedBlockInBox(embedBlockID string, includeIDs []string, headingMode int, breadcrumb bool, boxID string) (ret []*EmbedBlock) {

View on GitHub (pinned to 9f775e8a12)