{"record":{"id":"d4a78d4dd65599a9","repo":"siyuan-note/siyuan","slug":"conf-language-112","errorCode":null,"errorMessage":"Conf.Language(112)","messagePattern":"Conf\\.Language\\(112\\)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"kernel/model/tag.go","lineNumber":128,"sourceCode":"\n\tindexHistoryDir(filepath.Base(historyDir), util.NewLute())\n\tsql.FlushQueue()\n\n\treloadTreeIDs = gulu.Str.RemoveDuplicatedElem(reloadTreeIDs)\n\tfor _, id := range reloadTreeIDs {\n\t\tReloadProtyle(id)\n\t}\n\n\tupdateAttributeViewBlockText(updateNodes)\n\n\tsql.FlushQueue()\n\tutil.PushClearProgress()\n\treturn\n}\n\nfunc RenameTag(oldLabel, newLabel string) (err error) {\n\tif invalidChar := treenode.ContainsMarker(newLabel); \"\" != invalidChar {\n\t\treturn fmt.Errorf(Conf.Language(112), invalidChar)\n\t}\n\n\tnewLabel = strings.TrimPrefix(newLabel, \"/\")\n\tnewLabel = strings.TrimSuffix(newLabel, \"/\")\n\tnewLabel = strings.TrimSpace(newLabel)\n\n\tif \"\" == newLabel {\n\t\treturn errors.New(Conf.Language(114))\n\t}\n\n\tif oldLabel == newLabel {\n\t\treturn\n\t}\n\n\tutil.PushEndlessProgress(Conf.Language(110))\n\tutil.RandomSleep(500, 1000)\n\n\ttags := sql.QueryTagSpansByLabel(oldLabel)","sourceCodeStart":110,"sourceCodeEnd":146,"githubUrl":"https://github.com/siyuan-note/siyuan/blob/8641553a1f07374001902d3ce773285db1292b2d/kernel/model/tag.go#L110-L146","documentation":"RenameTag rejects a new tag label containing marker characters (characters with special meaning in SiYuan's tag/hierarchy syntax, e.g. markers checked by treenode.ContainsMarker). The localized message Conf.Language(112) is formatted with the offending character so the user knows exactly which character is illegal.","triggerScenarios":"Calling RenameTag (via renameTag API, tagRename, or a programmatic caller) with newLabel containing any character returned by treenode.ContainsMarker — e.g. characters that would break tag-tree parsing or block content markers.","commonSituations":"Paste of text containing markup/markdown special characters into the rename dialog; automation building tag names from arbitrary strings without sanitization; including slash/hierarchy separators where not allowed after trimming.","solutions":["Remove the reported invalid character from the new tag name and retry","Sanitize the label before calling the API: strip marker characters and verify treenode.ContainsMarker returns \"\"","Pre-validate in the UI/dialog before submitting the rename request"],"exampleFix":"// before: new label contains a marker character\nnewLabel := \"project/todo\"\n// after: sanitized label\nnewLabel := \"project-todo\"\nif c := treenode.ContainsMarker(newLabel); c != \"\" { /* reject before calling RenameTag */ }","handlingStrategy":"validation","validationCode":"function assertValidTagName(label) {\n  // marker characters must be absent before calling RenameTag\n  const markers = /[\\\\/<>\"'|?*:#[\\]]/; // extend to full marker set used by treenode.ContainsMarker\n  const m = label.match(markers);\n  if (m) throw new Error(`tag name contains invalid character: ${m[0]}`);\n}","typeGuard":null,"tryCatchPattern":"try {\n  await fetchPost(\"/api/tag/renameTag\", { oldLabel, newLabel });\n} catch (e) {\n  if (/invalid character/i.test(e.message)) {\n    // extract the offending character from the message and re-prompt the user\n  }\n}","preventionTips":["Sanitize tag labels from user input/clipboard before renaming","Reject any label where a marker-character check fails, before the API call","Strip or escape markup-like characters when generating tag names programmatically","Show the offending character (the error formats it) back to the user in UI flows"],"tags":["tag","validation","naming"],"backgroundTag":"invalid-argument-value","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"}