siyuan-note/siyuan · warning

Conf.Language(132)

Error message

Conf.Language(132)

What it means

FindReplaceInBox rejects replace operations whose method is 2 (SQL). Executing arbitrary SQL while replacing text would replace matched block content unreliably and unsafely, so the kernel refuses up front with the localized message Conf.Language(132) ("Replace is not supported for SQL queries").

Solutions

  1. Switch the search dialog to text, query-syntax, or regex mode (method 0/1/3) before replacing
  2. For SQL-driven bulk edits, write a transaction that updates the target blocks via the block update API instead of using replace
  3. If scripting, pass method=3 (regex) to achieve SQL-like precision over block content

Example fix

// before
FindReplace(keyword, repl, types, subTypes, 2 /* SQL */, ids, paths, boxes)
// after
FindReplace(keyword, repl, types, subTypes, 3 /* regex or 0=text */, ids, paths, boxes)
Defensive patterns

Strategy: validation

Validate before calling

// Reject SQL mode before invoking replace
if method == 2 {
    return errors.New("replace is not supported in SQL search mode; use method 0/1/3")
}

Type guard

// TS caller: const canReplace = (m: number) => [0, 1, 3].includes(m);

Try / catch

err := FindReplace(keyword, repl, types, subTypes, method, ids, paths, boxes)
if err != nil && err.Error() == Conf.Language(132) {
    // notify user to switch from SQL mode
}

Prevention

When it happens

Trigger: Calling FindReplaceInBox(..., method=2, ...) — i.e. the search dialog is in SQL mode and the user pressed replace-all; kernel callers findReplace/FindReplace forward the UI's current method value.

Common situations: A user runs a search in SQL query mode in the Replace tab and clicks Replace All; an automation script copies the search method parameter (2) into a replace call.

Understand the failure class

Background: UnsupportedOperationException and "is not supported" errors: when a library deliberately refuses a call — this error's family across 30 libraries.

Related errors


AI-assisted analysis of siyuan-note/siyuan@8641553a1f (2026-09-11). Data as JSON: /api/errors/8d40edcf7bf93069. Report an issue: GitHub.

Appendix: source

Thrown at kernel/model/search.go:636

	}
	boxIDs = gulu.Str.RemoveDuplicatedElem(boxIDs)
	boxNames := Conf.BoxNames(boxIDs)
	for _, b := range blocks {
		name := boxNames[b.Box]
		b.HPath = util.EscapeHTML(name) + b.HPath
	}
}

func FindReplace(keyword, replacement string, replaceTypes map[string]bool, ids []string, paths, boxes []string, types, subTypes map[string]bool, method, orderBy, groupBy int) (err error) {
	// orderBy 和 groupBy 仅用于兼容现有调用,替换目标不依赖搜索结果的展示顺序和分组方式。
	return FindReplaceInBox(keyword, replacement, replaceTypes, ids, paths, boxes, types, subTypes, method, "")
}

// FindReplaceInBox 与 FindReplace 一致,但按 boxID 路由到加密 db 或全局 db。
func FindReplaceInBox(keyword, replacement string, replaceTypes map[string]bool, ids []string, paths, boxes []string, types, subTypes map[string]bool, method int, boxID string) (err error) {
	// method:0:文本,1:查询语法,2:SQL,3:正则表达式
	if 2 == method {
		err = errors.New(Conf.Language(132))
		return
	}

	if 1 == method {
		// 将查询语法等价于关键字,因为 keyword 参数已经是结果关键字了
		// Find and replace supports query syntax https://github.com/siyuan-note/siyuan/issues/14937
		method = 0
	}

	// No longer trim spaces for the keyword and replacement https://github.com/siyuan-note/siyuan/issues/9229
	if keyword == replacement {
		return
	}

	r, _ := regexp.Compile(keyword)
	escapedKey := util.EscapeHTML(keyword)
	escapedKey = strings.ReplaceAll(escapedKey, """, """)
	escapedKey = strings.ReplaceAll(escapedKey, "'", "'")

View on GitHub (pinned to 8641553a1f)