siyuan-note/siyuan · error
Bookmark cannot be empty
Error message
Bookmark cannot be empty
What it means
model.RenameBookmark rejects a new bookmark name that is empty after strings.TrimSpace. This is the second validation, after the marker check, and uses localized message 126 ('Bookmark cannot be empty'). An empty string is the API-supported way to signal invalid input, not a delete — bookmarks are removed by unsetting them on blocks, not renamed to nothing.
Solutions
- Require a non-empty trimmed name in the UI before calling the API
- To remove a bookmark from blocks, set/unset the 'bookmark' attribute via setBlockAttrs instead of renaming to empty
- Guard scripts: skip the call when !newBookmark.trim()
Example fix
// before
renameBookmark(oldName, ''); // error
// after
if (newName.trim()) { renameBookmark(oldName, newName.trim()); } Defensive patterns
Strategy: validation
Validate before calling
const name = String(newBookmark ?? '').trim();
if (!name) throw new Error('bookmark name required'); Prevention
- Disable submit until the name is non-empty after trim
- To remove a bookmark, unset the block's 'bookmark' attribute instead of renaming
When it happens
Trigger: POST /api/bookmark/renameBookmark with newBookmark '', ' ', or a string that is only whitespace; also a name that was entirely marker characters is caught earlier, not here.
Common situations: Forms that submit before the user types a name, or scripts that pass an undefined/null coerced to '' when the desired name field is missing.
Related errors
- Do not include Markdown syntax marker
- AI editor action must not be empty
- block [ ] type is locked: expected , got
- block swap requires two non-document blocks
- can not remove [ ] caused by it is a reserved file
AI-assisted analysis of siyuan-note/siyuan@afa823b6b4 (2026-08-18).
Data as JSON: /api/errors/1f94c7e08043e391.
Report an issue: GitHub.
Appendix: source
Thrown at kernel/model/bookmark.go:103
util.RandomSleep(50, 150)
}
indexHistoryDir(filepath.Base(historyDir), util.NewLute())
sql.FlushQueue()
util.ReloadUI()
return
}
func RenameBookmark(oldBookmark, newBookmark string) (err error) {
if invalidChar := treenode.ContainsMarker(newBookmark); "" != invalidChar {
return fmt.Errorf(Conf.Language(112), invalidChar)
}
newBookmark = strings.TrimSpace(newBookmark)
if "" == newBookmark {
return errors.New(Conf.Language(126))
}
if oldBookmark == newBookmark {
return
}
util.PushEndlessProgress(Conf.Language(110))
defer util.ClearPushProgress(100)
bookmarks := sql.QueryBookmarkBlocks()
treeBlocks := map[string][]string{}
for _, bm := range bookmarks {
if blocks, ok := treeBlocks[bm.RootID]; !ok {
treeBlocks[bm.RootID] = []string{bm.ID}
} else {
treeBlocks[bm.RootID] = append(blocks, bm.ID)
}
}View on GitHub (pinned to afa823b6b4)