{"record":{"id":"774c4e36d3187221","repo":"siyuan-note/siyuan","slug":"sql-search-mode-does-not-support-the-replace-operation","errorCode":null,"errorMessage":"SQL search mode does not support the replace operation, please use another search method","messagePattern":"SQL search mode does not support the replace operation, please use another search method","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"kernel/model/search.go","lineNumber":636,"sourceCode":"\t}\n\tboxIDs = gulu.Str.RemoveDuplicatedElem(boxIDs)\n\tboxNames := Conf.BoxNames(boxIDs)\n\tfor _, b := range blocks {\n\t\tname := boxNames[b.Box]\n\t\tb.HPath = util.EscapeHTML(name) + b.HPath\n\t}\n}\n\nfunc FindReplace(keyword, replacement string, replaceTypes map[string]bool, ids []string, paths, boxes []string, types, subTypes map[string]bool, method, orderBy, groupBy int) (err error) {\n\t// orderBy 和 groupBy 仅用于兼容现有调用，替换目标不依赖搜索结果的展示顺序和分组方式。\n\treturn FindReplaceInBox(keyword, replacement, replaceTypes, ids, paths, boxes, types, subTypes, method, \"\")\n}\n\n// FindReplaceInBox 与 FindReplace 一致，但按 boxID 路由到加密 db 或全局 db。\nfunc FindReplaceInBox(keyword, replacement string, replaceTypes map[string]bool, ids []string, paths, boxes []string, types, subTypes map[string]bool, method int, boxID string) (err error) {\n\t// method：0：文本，1：查询语法，2：SQL，3：正则表达式\n\tif 2 == method {\n\t\terr = errors.New(Conf.Language(132))\n\t\treturn\n\t}\n\n\tif 1 == method {\n\t\t// 将查询语法等价于关键字，因为 keyword 参数已经是结果关键字了\n\t\t// Find and replace supports query syntax https://github.com/siyuan-note/siyuan/issues/14937\n\t\tmethod = 0\n\t}\n\n\t// No longer trim spaces for the keyword and replacement https://github.com/siyuan-note/siyuan/issues/9229\n\tif keyword == replacement {\n\t\treturn\n\t}\n\n\tr, _ := regexp.Compile(keyword)\n\tescapedKey := util.EscapeHTML(keyword)\n\tescapedKey = strings.ReplaceAll(escapedKey, \"&#34;\", \"&quot;\")\n\tescapedKey = strings.ReplaceAll(escapedKey, \"&#39;\", \"'\")","sourceCodeStart":618,"sourceCodeEnd":654,"githubUrl":"https://github.com/siyuan-note/siyuan/blob/9f775e8a12daef8255556097396f9b2739078892/kernel/model/search.go#L618-L654","documentation":"FindReplaceInBox explicitly rejects SQL search mode (method == 2): replacing text found by a raw SQL query is not supported because SQL matches cannot be reliably mapped back to editable text ranges. The error message is i18n language string 132 telling the user to choose another search method.","triggerScenarios":"Calling FindReplace or FindReplaceInBox with method=2 (SQL) and a non-empty replacement — the check fires before any search runs.","commonSituations":"Scripts or UI automation reusing the last search method (SQL) when issuing a replace; users switching from search-only to replace without changing the method dropdown.","solutions":["Use method 0 (text), 1 (query syntax) or 3 (regex) for the replace operation","Run the SQL query separately to collect IDs, then replace per block with a supported method","Update the calling UI to disable or remap SQL mode when a replacement is requested"],"exampleFix":"// before\nerr := model.FindReplace(k, r, types, ids, paths, boxes, method /* 2 = SQL */, replaceTypes)\n// after\nif method == 2 {\n    method = 0 // fall back to text search for replace\n}\nerr := model.FindReplace(k, r, types, ids, paths, boxes, method, replaceTypes)","handlingStrategy":"validation","validationCode":"if (method === 2 && replacement) { throw new Error('SQL mode cannot replace; use text/query/regex') }","typeGuard":null,"tryCatchPattern":"try { await api.findReplace(k, r, { method }) } catch (e) { if (String(e).includes('replace operation')) { notifyUserToChangeSearchMethod(); } else throw e }","preventionTips":["Map method codes explicitly (0=text, 1=query, 2=SQL, 3=regex) and guard SQL at the UI level","Never send a replacement string with method=2","Offer users a fallback method when they arrive at SQL mode with replace enabled"],"tags":["find-replace","unsupported-operation","siyuan"],"backgroundTag":"unsupported-operation","analyzedSha":"9f775e8a12daef8255556097396f9b2739078892","analyzedAt":"2026-09-19T03:17:15.984Z","contentChangedAt":"2026-09-19T03:17:15.984Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}