siyuan-note/siyuan · error
invalid .sy base name [%s]: stem is not a node ID
Error message
invalid .sy base name [%s]: stem is not a node ID
What it means
Returned by `filesys.SyObjectBase` when the `.sy` basename's stem (the filename minus `.sy`) does not match `ast.IsNodeIDPattern`. SiYuan `.sy` files are keyed by node IDs (the standard block-ID format used throughout the kernel), so the stem must be a valid node ID for the AAD to bind to a real object and remain decryptable after moves.
Source
Thrown at kernel/filesys/crypto_hook.go:116
}
return util.DecryptWithAAD(fileKey, data, []byte(aad))
}
// SyObjectBase 从 box 内相对路径提取稳定文件基名并校验合法性。
// 接受形如 <rootID>.sy 的基名:扩展名必须是 .sy,且 stem 是合法节点 ID。
// 非法扩展名或非节点 ID 模式返回错误,避免把任意路径当 AAD 绑定物产生不可解密的数据。
// 由 filesys、model 历史查看/回滚、import 等所有 .sy 加解密路径共同使用,保证 AAD 一致。
func SyObjectBase(relativePath string) (string, error) {
base := relativePath
if idx := strings.LastIndexAny(relativePath, "/\\"); idx >= 0 {
base = relativePath[idx+1:]
}
if !strings.HasSuffix(base, ".sy") {
return "", fmt.Errorf("invalid .sy base name [%s]: must end with .sy", base)
}
stem := strings.TrimSuffix(base, ".sy")
if !ast.IsNodeIDPattern(stem) {
return "", fmt.Errorf("invalid .sy base name [%s]: stem is not a node ID", base)
}
return base, nil
}
// SyAAD 构造 .sy 密文的 AAD:siyuan:file:<boxID>:<稳定文件基名>。
// 父目录不进 AAD——同 box 内文件名不变的移动允许原样 Rename 密文,内容/box/类型/对象 ID 仍受认证。
func SyAAD(boxID, relativePath string) (string, error) {
base, err := SyObjectBase(relativePath)
if err != nil {
return "", err
}
return "siyuan:file:" + boxID + ":" + base, nil
}
// encryptedBox 判断 boxID 是否为已解锁的加密 box,供 filesys 内部分流(如静默修正禁用)。
// 通过 DEKProvider 探测:返回非 nil dek 即加密且已解锁。
func encryptedBox(boxID string) bool {
if DEKProvider == nil {View on GitHub (pinned to 251596fc0d)
Solutions
- Rename the file to `<valid-node-id>.sy`, where the node ID is the document's root block ID.
- Regenerate the document so the kernel writes the correctly-named `.sy` file.
- If decrypting legacy data, confirm the file was not renamed outside SiYuan; restore from history if so.
Example fix
// before // file on disk: data/<box>/draft.sy // after // file on disk: data/<box>/20240101000000-abcdef1234567.sy
Defensive patterns
Strategy: type-guard
Validate before calling
// Confirm the stem is a node ID before calling SyObjectBase:
stem := strings.TrimSuffix(base, ".sy")
if !ast.IsNodeIDPattern(stem) {
return "", fmt.Errorf("stem not a node ID: %s", base)
} Type guard
func isValidSyBasename(base string) bool {
if !strings.HasSuffix(base, ".sy") {
return false
}
return ast.IsNodeIDPattern(strings.TrimSuffix(base, ".sy"))
} Prevention
- Always name .sy files by the document root block ID.
- Never hand-rename .sy files in an encrypted notebook.
- When importing, generate IDs through the kernel, not by string manipulation.
When it happens
Trigger: A `.sy` file whose name is not a node ID, e.g. `notes.sy`, `temp.sy`, or `My Document.sy`. The check protects the encryption layer from attaching AAD to arbitrary filenames that would later fail to decrypt.
Common situations: Manually created or renamed `.sy` files in an encrypted notebook; import logic that generated a non-ID filename; a corrupted/tampered tree whose root ID was rewritten to an invalid string.
Related errors
- invalid .sy base name [%s]: must end with .sy
- invalid new item template id [%s]
- path belongs to encrypted notebook [%s]: %s
- renaming assets in encrypted notebooks is not supported
- password must not be empty
AI-assisted analysis of siyuan-note/siyuan@251596fc0d (2026-08-12).
Data as JSON: /api/errors/6b232af8e87b2e9c.
Report an issue: GitHub.