{"record":{"id":"d3709f691edd32cb","repo":"siyuan-note/siyuan","slug":"do-not-include-symbols","errorCode":null,"errorMessage":"Do not include symbols \\ / : * ? \" ' < > |","messagePattern":"Do not include symbols \\\\ / : \\* \\? \" ' < > \\|","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"kernel/model/repository.go","lineNumber":1733,"sourceCode":"}\n\nfunc TagSnapshot(id, name string) (err error) {\n\tassetDownloadSourceMu.RLock()\n\tdefer assetDownloadSourceMu.RUnlock()\n\tif 1 > len(Conf.Repo.Key) {\n\t\terr = errors.New(Conf.Language(26))\n\t\treturn\n\t}\n\n\tname = util.RemoveInvalid(name)\n\tname = strings.TrimSpace(name)\n\tif \"\" == name {\n\t\terr = errors.New(Conf.Language(142))\n\t\treturn\n\t}\n\n\tif !gulu.File.IsValidFilename(name) {\n\t\terr = errors.New(Conf.Language(151))\n\t\treturn\n\t}\n\n\trepo, err := newRepositoryWithAssetSourceLocked()\n\tif err != nil {\n\t\treturn\n\t}\n\n\tindex, err := repo.GetIndex(id)\n\tif err != nil {\n\t\treturn\n\t}\n\n\tif err = repo.AddTag(index.ID, name); err != nil {\n\t\tmsg := fmt.Sprintf(\"Add tag to data snapshot [%s] failed: %s\", index.ID, err)\n\t\tutil.PushStatusBar(msg)\n\t\treturn\n\t}","sourceCodeStart":1715,"sourceCodeEnd":1751,"githubUrl":"https://github.com/siyuan-note/siyuan/blob/9f775e8a12daef8255556097396f9b2739078892/kernel/model/repository.go#L1715-L1751","documentation":"After the empty check, TagSnapshot validates the name with gulu.File.IsValidFilename; names containing filesystem-invalid symbols \\ / : * ? \" ' < > | are rejected with errors.New(Conf.Language(151)). This is because tags map to snapshot directory/file names on disk and in cloud storage, so OS-illegal characters would break the repo layout.","triggerScenarios":"Calling TagSnapshot with a name containing any of \\ / : * ? \" ' < > | that survives util.RemoveInvalid, so gulu.File.IsValidFilename fails and Language 151 is returned.","commonSituations":"Users typing tags like 'backup 2024/05' or using OS path separators; names derived from document titles that contain colons or quotes; automation passing raw filenames with Windows-illegal characters.","solutions":["Remove or replace the forbidden characters (\\ / : * ? \" ' < > |) from the tag name before calling TagSnapshot","Rely on util.RemoveInvalid then verify the result with gulu.File.IsValidFilename on the caller side to fail fast","Use letters, digits, spaces, hyphens and underscores, which pass filename validation on all platforms","If the message is Language 151, the repo key is fine — only the name needs fixing; no other state must change"],"exampleFix":"// before\nname := \"backup: 2024/05\"\nmodel.TagSnapshot(id, name) // fails: contains ':' and '/'\n// after\nname := \"backup: 2024/05\"\nname = strings.Map(func(r rune) rune {\n    if strings.ContainsRune(`\\/:*?\"'<>|`, r) { return '-' }\n    return r\n}, name)\nmodel.TagSnapshot(id, name)","handlingStrategy":"validation","validationCode":"function isValidTagName(name) {\n  return name.length > 0 && !/[\\\\/:*?\"'<>|]/.test(name);\n}\n// call before TagSnapshot\nif (!isValidTagName(input)) throw new Error('Do not include symbols \\\\ / : * ? \" \\' < > |');","typeGuard":null,"tryCatchPattern":"try {\n    await fetchPost('/api/repo/tagSnapshot', {id, name});\n} catch (e) {\n    if (e.msg.includes('Do not include symbols')) highlightInvalidCharsInInput();\n}","preventionTips":["Filter or replace \\ / : * ? \" ' < > | in the input field as the user types","Reuse the kernel's rule (gulu.File.IsValidFilename semantics) in client-side validation","Prefer letters, digits, spaces, hyphens, underscores for tag names","Show the allowed-character rule next to the tag input to prevent the error entirely"],"tags":["validation","input","filename","snapshot","illegal-characters"],"backgroundTag":"invalid-identifier-format","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"}