siyuan-note/siyuan · error

data block DOM failed

Error message

data block DOM failed: %w

What it means

parseBlockUpdateData wraps errors from DataBlockDOM (the markdown-to-block-DOM conversion) with the context "data block DOM failed". It is thrown when markdown input supplied to buildBlockUpdateOperations cannot be converted to valid block DOM — most commonly because it contains an invalid explicit block ID (the wrapped error), or because the markdown itself fails conversion.

Solutions

  1. Inspect the wrapped inner error (likely "found invalid ID [...]") and fix or remove the offending {: id="..."} attribute in the markdown payload
  2. Strip explicit block IDs and let SiYuan generate them during conversion
  3. Validate markdown IDs client-side against the 14-character SiYuan ID pattern before calling the API

Example fix

// before
{"dataType": "markdown", "data": "text {: id=\"bad-id\"}"}
// after
{"dataType": "markdown", "data": "text"}
Defensive patterns

Strategy: try-catch

Validate before calling

if (payload.dataType === "markdown" && /\{:\s*id="(?!\d{14}-[0-9a-z]{7}")/.test(payload.data)) {
  throw new Error("invalid explicit block ID in markdown payload");
}

Try / catch

try {
  await updateBlock({ id, dataType: "markdown", data });
} catch (e) {
  if (String(e.msg).startsWith("data block DOM failed")) {
    // unwrap: usually "found invalid ID [...]" — sanitize data and retry
  }
}

Prevention

When it happens

Trigger: Calling the block update flow (buildBlockUpdateOperations / /api/block/updateBlock) with dataType "markdown" where DataBlockDOM returns an error, e.g. markdown containing an explicit block ID that fails IsNodeIDPattern validation.

Common situations: API clients sending markdown with foreign/custom ID attributes; scripts updating blocks with content copied from other outliners that embed their own identifier syntax.

Understand the failure class

Background: "Invalid ... format", "must be in format X", "does not look like a ..." — invalid argument format errors across CLI tools and libraries — this error's family across 17 libraries.

Related errors


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

Appendix: source

Thrown at kernel/model/block_update.go:209

				invalidID = n.ID
				return ast.WalkStop
			}
			return ast.WalkContinue
		})
	}
	if "" != invalidID {
		return "", errors.New("found invalid ID [" + invalidID + "]")
	}
	return
}

func parseBlockUpdateData(data, dataType string, luteEngine *lute.Lute) (ret string, tree *parse.Tree, err error) {
	ret = data
	switch dataType {
	case "markdown":
		ret, err = DataBlockDOM(data, luteEngine)
		if err != nil {
			err = fmt.Errorf("data block DOM failed: %w", err)
			return
		}
	case "dom":
	default:
		err = fmt.Errorf("unsupported block data type [%s]", dataType)
		return
	}

	tree = luteEngine.BlockDOM2Tree(ret)
	if nil == tree || nil == tree.Root || nil == firstContentBlock(tree.Root) {
		err = errors.New("parse tree failed")
	}
	return
}

func normalizeBlockUpdateTree(oldNode *ast.Node, tree *parse.Tree, luteEngine *lute.Lute) (ret *parse.Tree, updatedNode *ast.Node, err error) {
	updatedNode, err = resolveBlockUpdateNode(oldNode, tree.Root)
	if err != nil {

View on GitHub (pinned to 9f775e8a12)