siyuan-note/siyuan · warning

Do not include symbols \ / : * ? " ' < > |

Error message

Do not include symbols \ / : * ? " ' < > |

What it means

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.

Solutions

  1. Remove the listed symbols from the new name and retry
  2. Pre-validate the input in the UI before submitting the rename
  3. Omit the file extension - the kernel appends the old extension automatically

Example fix

// before
newPath, err := model.RenameAsset(oldPath, "report: 2024?")

// after: sanitize first
newName = strings.TrimSpace(newName)
for _, r := range `\/:*?"'<>|` {
	newName = strings.ReplaceAll(newName, string(r), "")
}
newPath, err := model.RenameAsset(oldPath, newName)
Defensive patterns

Strategy: validation

Validate before calling

newName = strings.TrimSpace(util.FilterUploadFileName(newName))
if !gulu.File.IsValidFilename(newName) {
	// reject in the UI before calling model.RenameAsset
}

Type guard

func isValidNewAssetName(s string) bool {
	s = strings.TrimSpace(s)
	if s == "" {
		return false
	}
	for _, r := range `\/:*?"'<>|` {
		if strings.ContainsRune(s, r) {
			return false
		}
	}
	return true
}

Try / catch

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.

Prevention

When it happens

Trigger: Calling rename with a newName that still contains any of \ / : * ? " ' < > | after util.FilterUploadFileName trimming; commonly names pasted from web page titles.

Common situations: Pasting titles like 'Report: 2024?' as asset names; cross-platform names with characters Windows forbids.

Related errors


AI-assisted analysis of siyuan-note/siyuan@afa823b6b4 (2026-08-18). Data as JSON: /api/errors/79a11266783fb174. Report an issue: GitHub.

Appendix: source

Thrown at kernel/model/assets.go:1547

	// 加密笔记本的资源磁盘文件名参与 AAD,重命名需要重新封装密文,当前不支持。
	if absPath, absErr := GetAssetAbsPathInBox(oldPath, ""); absErr == nil {
		if IsEncryptedAssetPath(absPath) {
			err = errors.New("renaming assets in encrypted notebooks is not supported")
			return
		}
	}

	newName = strings.TrimSpace(newName)
	newName = util.FilterUploadFileName(newName)
	if path.Base(oldCleanPath) == newName {
		return
	}
	if "" == newName {
		return
	}

	if !gulu.File.IsValidFilename(newName) {
		err = errors.New(Conf.Language(151))
		return
	}

	newName = util.AssetName(newName+filepath.Ext(oldCleanPath), ast.NewNodeID())
	parentDir := path.Dir(oldCleanPath)
	newPath = path.Join(parentDir, newName)
	oldAbsPath, getErr := GetAssetAbsPathInBox(oldPath, "")
	if getErr != nil {
		logging.LogErrorf("get asset [%s] abs path failed: %s", oldPath, getErr)
		return
	}
	newAbsPath := filepath.Join(filepath.Dir(oldAbsPath), newName)
	filelock.Lock(oldAbsPath)
	if err = os.Rename(oldAbsPath, newAbsPath); err != nil {
		if err = gulu.File.Copy(oldAbsPath, newAbsPath); err != nil {
			filelock.Unlock(oldAbsPath)
			logging.LogErrorf("copy asset [%s] failed: %s", oldAbsPath, err)
			return

View on GitHub (pinned to afa823b6b4)