siyuan-note/siyuan · warning

renaming assets in encrypted notebooks is not supported

Error message

renaming assets in encrypted notebooks is not supported

What it means

Returned by RenameAsset (assets.go:1496) when the resolved absolute path of the asset being renamed belongs to an encrypted notebook (IsEncryptedAssetPath(absPath) is true). Encrypted notebooks incorporate the on-disk asset filename into the AAD (additional authenticated data) of the ciphertext, so renaming would invalidate the authenticated envelope; the kernel refuses rather than re-wrap the key material.

Source

Thrown at kernel/model/assets.go:1496

	util.RemoveAssetText(relativePath)

	IncSync()

	indexHistoryDir(filepath.Base(historyDir), util.NewLute())
	cache.RemoveAsset(relativePath)
	return
}

func RenameAsset(oldPath, newName string) (newPath string, err error) {
	util.PushEndlessProgress(Conf.Language(110))
	defer util.PushClearProgress()

	oldCleanPath := AssetPathWithoutQuery(oldPath)

	// 加密笔记本的资源磁盘文件名参与 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
	}

View on GitHub (pinned to 251596fc0d)

Solutions

  1. Do not rename assets inside encrypted notebooks from the UI/API; this is an intentional limitation, not a bug.
  2. If a rename is required, move the asset out of the encrypted notebook (or decrypt the notebook temporarily), rename, then re-embed — the filename will then not be part of the AAD.
  3. Verify the target box's encryption status before offering a rename action in the UI so the option is hidden for encrypted boxes.

Example fix

// before: rename offered unconditionally
model.RenameAsset(oldPath, newName)

// after: gate the UI action on encryption status
absPath, absErr := model.GetAssetAbsPathInBox(oldPath, "")
if absErr == nil && model.IsEncryptedAssetPath(absPath) {
    showMessage(window.siyuan.languages["renameDisabledEncrypted"])
    return
}
model.RenameAsset(oldPath, newName)
Defensive patterns

Strategy: validation

Validate before calling

// Hide/disable rename for assets inside encrypted notebooks.
const absPath = await getAssetAbsPathInBox(oldPath)
if (absPath && await isEncryptedAssetPath(absPath)) {
  // do not offer rename
  return
}

Try / catch

// This is a hard limitation; do not retry, inform the user instead.
try { await renameAsset(oldPath, newName) }
catch (e) { if (/encrypted notebooks/i.test(e.message)) showInfo(e.message) else throw e }

Prevention

When it happens

Trigger: Calling /api/asset/renameAsset with an oldPath that resolves (via GetAssetAbsPathInBox) inside a notebook whose box.conf is encrypted, i.e. an asset stored under an encrypted box's data/<boxid>/assets/ tree. Note the check runs only when GetAssetAbsPathInBox returns no error; if the path cannot be resolved the rename proceeds and fails later.

Common situations: User enables notebook encryption then tries to rename an embedded image/PDF from the asset menu; plugin or sync-driven rename targeting an encrypted box; attempting to rename a shared asset referenced from an encrypted notebook.

Related errors


AI-assisted analysis of siyuan-note/siyuan@251596fc0d (2026-08-12). Data as JSON: /api/errors/ba25f11a06d70b6f. Report an issue: GitHub.