{"record":{"id":"e0cb6fa1bfa1a6e8","repo":"siyuan-note/siyuan","slug":"conf-language-112-bookmark","errorCode":null,"errorMessage":"Conf.Language(112)","messagePattern":"Conf\\.Language\\(112\\)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"kernel/model/bookmark.go","lineNumber":100,"sourceCode":"\t\t\tif err = writeTreeUpsertQueue(tree); err != nil {\n\t\t\t\tutil.ClearPushProgress(100)\n\t\t\t\treturn\n\t\t\t}\n\t\t}\n\n\t\tutil.RandomSleep(50, 150)\n\t}\n\n\tindexHistoryDir(filepath.Base(historyDir), util.NewLute())\n\tsql.FlushQueue()\n\n\tutil.ReloadUI()\n\treturn\n}\n\nfunc RenameBookmark(oldBookmark, newBookmark string) (err error) {\n\tif invalidChar := treenode.ContainsMarker(newBookmark); \"\" != invalidChar {\n\t\treturn fmt.Errorf(Conf.Language(112), invalidChar)\n\t}\n\n\tnewBookmark = strings.TrimSpace(newBookmark)\n\tif \"\" == newBookmark {\n\t\treturn errors.New(Conf.Language(126))\n\t}\n\n\tif oldBookmark == newBookmark {\n\t\treturn\n\t}\n\n\tutil.PushEndlessProgress(Conf.Language(110))\n\tdefer util.ClearPushProgress(100)\n\n\tbookmarks := sql.QueryBookmarkBlocks()\n\ttreeBlocks := map[string][]string{}\n\tfor _, bm := range bookmarks {\n\t\tif blocks, ok := treeBlocks[bm.RootID]; !ok {","sourceCodeStart":82,"sourceCodeEnd":118,"githubUrl":"https://github.com/siyuan-note/siyuan/blob/9f775e8a12daef8255556097396f9b2739078892/kernel/model/bookmark.go#L82-L118","documentation":"RenameBookmark validates the new bookmark name before applying it. If the name contains characters that SiYuan reserves for block-mark syntax (detected by treenode.ContainsMarker), the rename is rejected with a localized message (language key 112) naming the offending character. Bookmark names are used in queries/menus so marker characters are forbidden.","triggerScenarios":"Calling RenameBookmark (or the bookmarkRename API) where `newBookmark` contains a marker character such as /, ^, or other Kramdown-reserved tokens used in block refs and search syntax.","commonSituations":"User pastes a path-like or markup-flavored name (e.g. 'work/project', '^todo') into the rename dialog; programmatic renames built from filenames or headings that include slashes.","solutions":["Remove the reserved marker characters from the new name (shown in the error message)","Sanitize input with a replacement character before calling, e.g. replace '/' with '-'","Show the localized error to the user and prompt for a different name"],"exampleFix":"// before\nerr := model.RenameBookmark(old, input) // input: \"work/project\"\n// after\nsanitized := strings.ReplaceAll(input, \"/\", \"-\")\nif c := treenode.ContainsMarker(sanitized); c != \"\" { return fmt.Errorf(\"invalid char %q\", c) }\nerr := model.RenameBookmark(old, sanitized)","handlingStrategy":"validation","validationCode":"if c := treenode.ContainsMarker(newName); c != \"\" { return fmt.Errorf(\"bookmark name may not contain %q\", c) }","typeGuard":null,"tryCatchPattern":"if err := model.RenameBookmark(old, name); err != nil {\n  // surface localized message to user and keep old name\n}","preventionTips":["Strip reserved marker characters (/, ^, etc.) from user input","Replace path-like separators in names derived from filenames","Preview the sanitized name in the UI before applying"],"tags":["go","kernel","bookmark","validation"],"backgroundTag":"invalid-argument-value","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"}