siyuan-note/siyuan · error

query embed block statement not found

Error message

query embed block statement not found

What it means

The GetQueryEmbedStatement function found a valid NodeBlockQueryEmbed block and loaded its tree, but the block has no child node of type NodeBlockQueryEmbedScript. This means the embed block exists but its SQL query statement content is missing, corrupted, or was never set. The script node is where the actual query text (e.g., 'SELECT * FROM blocks WHERE...') is stored in the AST.

Source

Thrown at kernel/model/search.go:305

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

	tree, loadErr := filesys.LoadTree(bt.BoxID, bt.Path, util.NewLute())
	if nil != loadErr {
		err = loadErr
		return
	}
	node := treenode.GetNodeInTree(tree, embedBlockID)
	if nil == node || ast.NodeBlockQueryEmbed != node.Type {
		err = ErrBlockNotFound
		return
	}
	scriptNode := node.ChildByType(ast.NodeBlockQueryEmbedScript)
	if nil == scriptNode {
		err = errors.New("query embed block statement not found")
		return
	}

	stmt = stdhtml.UnescapeString(scriptNode.TokensStr())
	stmt = strings.ReplaceAll(stmt, editor.IALValEscNewLine, "\n")
	boxID = bt.BoxID
	return
}

func SearchEmbedBlock(embedBlockID, stmt string, excludeIDs []string, headingMode int, breadcrumb bool) (ret []*EmbedBlock) {
	return SearchEmbedBlockInBox(embedBlockID, stmt, excludeIDs, headingMode, breadcrumb, "")
}

// SearchEmbedBlockInBox 与 SearchEmbedBlock 一致,但按 boxID 路由 SQL 到加密 content db。
// 加密笔记本的嵌入块查询走独立加密库(全局 siyuan.db 不含加密数据),boxID 为空时落回全局库。
func SearchEmbedBlockInBox(embedBlockID, stmt string, excludeIDs []string, headingMode int, breadcrumb bool, boxID string) (ret []*EmbedBlock) {
	return searchEmbedBlockInBox(embedBlockID, stmt, excludeIDs, headingMode, breadcrumb, boxID, true)
}

View on GitHub (pinned to 251596fc0d)

Solutions

  1. Inspect the .sy file for the embed block to verify whether the script child node exists in the serialized AST
  2. If the script is genuinely missing, recreate the embed block through the editor UI to regenerate the proper node structure
  3. If this occurs after a sync, check for sync conflicts in the .sy file and resolve them to restore the complete embed block AST
  4. As a fallback, the caller can catch this error and prompt the user to re-enter the embed query

Example fix

// before
stmt, boxID, err := model.GetQueryEmbedStatement(embedBlockID)
if err != nil {
    log.Fatal(err)
}

// after
stmt, boxID, err := model.GetQueryEmbedStatement(embedBlockID)
if err != nil && err.Error() == "query embed block statement not found" {
    // prompt user to recreate the embed block query
    stmt = ""
    err = nil
}
Defensive patterns

Strategy: validation

Validate before calling

// Before extracting embed statement, verify script node exists
// This requires loading the tree and checking the AST node structure
bt := treenode.GetBlockTree(embedBlockID)
if bt != nil {
    tree, _ := filesys.LoadTree(bt.BoxID, bt.Path, util.NewLute())
    if tree != nil {
        node := treenode.GetNodeInTree(tree, embedBlockID)
        if node != nil && node.ChildByType(ast.NodeBlockQueryEmbedScript) == nil {
            // script node missing — block is malformed
            return "", "", nil
        }
    }
}

Try / catch

// Handle missing embed script gracefully
stmt, boxID, err := model.GetQueryEmbedStatement(embedBlockID)
if err != nil && strings.Contains(err.Error(), "statement not found") {
    // embed block has no query — treat as empty
    stmt = ""
    err = nil
}

Prevention

When it happens

Trigger: Calling GetQueryEmbedStatement on an embed block whose AST node has no NodeBlockQueryEmbedScript child. This can happen with malformed or partially constructed embed blocks, blocks whose script content was deleted or emptied, or data corruption in the .sy file where the script child node is missing from the serialized tree.

Common situations: An embed block was created programmatically or via direct .sy file editing without including the script content. Also occurs when a data sync conflict partially merges an embed block, keeping the container node but dropping the script child. Rare but possible after a Lute version upgrade that changes the expected child node structure of embed blocks.

Related errors


AI-assisted analysis of siyuan-note/siyuan@251596fc0d (2026-08-12). Data as JSON: /api/errors/e5e576fa5c7104cd. Report an issue: GitHub.