siyuan-note/siyuan · error
invalid .sy base name
Error message
invalid .sy base name [%s]: stem is not a node ID
What it means
After confirming the ".sy" suffix, SyObjectBase requires the stem to match ast.IsNodeIDPattern, i.e. a SiYuan node ID like "20260101120000-abcdefg". Because the AAD binds the ciphertext to the object ID, only node-ID-named documents qualify. The error means the suffix was fine but the stem is not a node ID.
Solutions
- Use the document's real node ID file name (look it up via the tree/block ID).
- Rename the file to its node ID, e.g. 20260101120000-abcdefg.sy, if it is genuinely a document.
- If the stem format is unexpected, regenerate the document ID and rebuild the .sy file through the normal write path.
Example fix
// before
SyObjectBase("notes.sy")
// after
SyObjectBase("20260101120000-abcdefg.sy") Defensive patterns
Strategy: validation
Validate before calling
const re = /^\d{14}-[0-9a-f]{7}\.sy$/;
if (!re.test(baseName)) throw new Error("base name is not a node ID .sy file"); Try / catch
base, err := filesys.SyObjectBase(relPath)
if err != nil {
// fall back to ID lookup before crypto operations
} Prevention
- Derive document file names from block/tree IDs, never from titles.
- Do not rename .sy files to human-readable names.
- Validate the yyyyMMddHHmmss-7hex ID pattern before calling.
When it happens
Trigger: Calling SyObjectBase with names like "notes.sy", "Untitled.sy", "123.sy", or a legacy/custom file name whose stem is not the yyyyMMddHHmmss-7hex node ID format.
Common situations: Imported or renamed documents that kept a human-readable file name; tests using fake .sy names; constructing document paths manually instead of from the tree ID.
Understand the failure class
Background: "invalid id" errors: invalid identifier format — why libraries reject IDs before lookup, and how to fix them — this error's family across 37 libraries.
Related errors
- Argon2id KeyLength must be 32
- Argon2id Memory too low (minimum 64 MB)
- cannot save incomplete notebook crypto configuration
- Conf.Language(317)
- current document ID is invalid
AI-assisted analysis of siyuan-note/siyuan@9f775e8a12 (2026-09-19).
Data as JSON: /api/errors/6b232af8e87b2e9c.
Report an issue: GitHub.
Appendix: 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 9f775e8a12)