{"record":{"id":"de191164a4d60c62","repo":"siyuan-note/siyuan","slug":"conf-language-126-localized-empty-bookmark-name","errorCode":null,"errorMessage":"Conf.Language(126) (localized empty-bookmark-name message)","messagePattern":"Conf\\.Language\\(126\\) \\(localized empty-bookmark-name message\\)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"kernel/model/bookmark.go","lineNumber":103,"sourceCode":"\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 {\n\t\t\ttreeBlocks[bm.RootID] = []string{bm.ID}\n\t\t} else {\n\t\t\ttreeBlocks[bm.RootID] = append(blocks, bm.ID)\n\t\t}\n\t}","sourceCodeStart":85,"sourceCodeEnd":121,"githubUrl":"https://github.com/siyuan-note/siyuan/blob/8641553a1f07374001902d3ce773285db1292b2d/kernel/model/bookmark.go#L85-L121","documentation":"A bookmark rename resolves to an empty name after trimming whitespace, which is not allowed because a bookmark must have a non-empty label. The localized empty-name message (Conf.Language(126)) is returned. Note the marker check runs before trimming, and the emptiness check runs after strings.TrimSpace, so a name of only spaces also lands here.","triggerScenarios":"Calling RenameBookmark with newBookmark == \"\" or a whitespace-only string (e.g. \"   \"); the rename dialog submitted with a cleared input field.","commonSituations":"User deletes all text in the rename input and confirms; automation scripts pass an empty string to clear a bookmark instead of using the proper remove-bookmark API.","solutions":["Provide a non-empty new bookmark name.","To remove a bookmark, call the dedicated remove/delete bookmark API instead of renaming to empty.","Validate client-side: trim the input and require length > 0 before invoking the API.","Show Conf.Language(126) in the UI to prompt the user for a valid name."],"exampleFix":"// before\nerr := model.RenameBookmark(old, \"\")\n// after\nname := strings.TrimSpace(input)\nif name == \"\" { return errors.New(\"bookmark name required\") }\nerr := model.RenameBookmark(old, name)","handlingStrategy":"validation","validationCode":"function isValidBookmarkName(name) { return typeof name === 'string' && name.trim().length > 0 }","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Require non-empty trimmed input in rename dialogs before submitting","Use the dedicated remove API to delete bookmarks instead of renaming to empty","Trim user input server-side and client-side consistently"],"tags":["bookmark","empty-value","validation"],"backgroundTag":"empty-required-field","analyzedSha":"8641553a1f07374001902d3ce773285db1292b2d","analyzedAt":"2026-09-11T16:08:28.414Z","contentChangedAt":"2026-09-11T16:08:28.414Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}