{"record":{"id":"79a11266783fb174","repo":"siyuan-note/siyuan","slug":"do-not-include-symbols-quot-039-lt","errorCode":null,"errorMessage":"Do not include symbols \\ / : * ? &quot; &#039; &lt; &gt; |","messagePattern":"Do not include symbols \\\\ / : \\* \\? &quot; &#039; &lt; &gt; \\|","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"kernel/model/assets.go","lineNumber":1547,"sourceCode":"\t// 加密笔记本的资源磁盘文件名参与 AAD，重命名需要重新封装密文，当前不支持。\n\tif absPath, absErr := GetAssetAbsPathInBox(oldPath, \"\"); absErr == nil {\n\t\tif IsEncryptedAssetPath(absPath) {\n\t\t\terr = errors.New(\"renaming assets in encrypted notebooks is not supported\")\n\t\t\treturn\n\t\t}\n\t}\n\n\tnewName = strings.TrimSpace(newName)\n\tnewName = util.FilterUploadFileName(newName)\n\tif path.Base(oldCleanPath) == newName {\n\t\treturn\n\t}\n\tif \"\" == newName {\n\t\treturn\n\t}\n\n\tif !gulu.File.IsValidFilename(newName) {\n\t\terr = errors.New(Conf.Language(151))\n\t\treturn\n\t}\n\n\tnewName = util.AssetName(newName+filepath.Ext(oldCleanPath), ast.NewNodeID())\n\tparentDir := path.Dir(oldCleanPath)\n\tnewPath = path.Join(parentDir, newName)\n\toldAbsPath, getErr := GetAssetAbsPathInBox(oldPath, \"\")\n\tif getErr != nil {\n\t\tlogging.LogErrorf(\"get asset [%s] abs path failed: %s\", oldPath, getErr)\n\t\treturn\n\t}\n\tnewAbsPath := filepath.Join(filepath.Dir(oldAbsPath), newName)\n\tfilelock.Lock(oldAbsPath)\n\tif err = os.Rename(oldAbsPath, newAbsPath); err != nil {\n\t\tif err = gulu.File.Copy(oldAbsPath, newAbsPath); err != nil {\n\t\t\tfilelock.Unlock(oldAbsPath)\n\t\t\tlogging.LogErrorf(\"copy asset [%s] failed: %s\", oldAbsPath, err)\n\t\t\treturn","sourceCodeStart":1529,"sourceCodeEnd":1565,"githubUrl":"https://github.com/siyuan-note/siyuan/blob/afa823b6b4e4f183511e0bc0a3be93caa94c7c97/kernel/model/assets.go#L1529-L1565","documentation":"RenameAsset validates the filtered new name with gulu.File.IsValidFilename; if it still contains any reserved character - backslash, slash, colon, asterisk, question mark, double quote, apostrophe, less-than, greater-than, pipe - the localized message listing the symbols (Conf.Language(151)) is returned and the rename is refused.","triggerScenarios":"Calling rename with a newName that still contains any of \\ / : * ? \" ' < > | after util.FilterUploadFileName trimming; commonly names pasted from web page titles.","commonSituations":"Pasting titles like 'Report: 2024?' as asset names; cross-platform names with characters Windows forbids.","solutions":["Remove the listed symbols from the new name and retry","Pre-validate the input in the UI before submitting the rename","Omit the file extension - the kernel appends the old extension automatically"],"exampleFix":"// before\nnewPath, err := model.RenameAsset(oldPath, \"report: 2024?\")\n\n// after: sanitize first\nnewName = strings.TrimSpace(newName)\nfor _, r := range `\\/:*?\"'<>|` {\n\tnewName = strings.ReplaceAll(newName, string(r), \"\")\n}\nnewPath, err := model.RenameAsset(oldPath, newName)","handlingStrategy":"validation","validationCode":"newName = strings.TrimSpace(util.FilterUploadFileName(newName))\nif !gulu.File.IsValidFilename(newName) {\n\t// reject in the UI before calling model.RenameAsset\n}","typeGuard":"func isValidNewAssetName(s string) bool {\n\ts = strings.TrimSpace(s)\n\tif s == \"\" {\n\t\treturn false\n\t}\n\tfor _, r := range `\\/:*?\"'<>|` {\n\t\tif strings.ContainsRune(s, r) {\n\t\t\treturn false\n\t\t}\n\t}\n\treturn true\n}","tryCatchPattern":"Check err from RenameAsset and keep the rename dialog open with the invalid characters highlighted so the user can correct the name; retry only after re-validation.","preventionTips":["Validate filenames client-side with the same character set","Strip extensions from user input - the kernel re-appends it","Normalize pasted titles before using them as asset names"],"tags":["validation","filename","rename","i18n"],"backgroundTag":"invalid-filename","analyzedSha":"afa823b6b4e4f183511e0bc0a3be93caa94c7c97","analyzedAt":"2026-08-18T17:04:10.865Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}