siyuan-note/siyuan · error
encrypted repository data is missing valid notebook context
Error message
encrypted repository data is missing valid notebook context
What it means
Inside OpenRepoSnapshotFile after reading file bytes: the data tests positive as ciphertext (util.IsCiphertext or the encryptedAssetMagic prefix) but the extracted payloadBoxID is empty or does not name a registered encrypted notebook. This is a deliberate fail-closed check: encrypted bytes without a decryptable notebook context must never be handed to a plaintext parser. Distinct from 866 (which lives in decryptRepoDataIfNeeded and keys off path validity) — here the check is on the snapshot payload path prefix.
Source
Thrown at kernel/model/repository.go:425
if err != nil {
return
}
data, err := repo.OpenFile(file)
if err != nil {
return
}
updated = file.Updated
repoPath := strings.TrimPrefix(file.Path, "/")
repoPathParts := strings.SplitN(repoPath, "/", 2)
payloadBoxID := ""
if len(repoPathParts) == 2 && ast.IsNodeIDPattern(repoPathParts[0]) {
payloadBoxID = repoPathParts[0]
}
if (util.IsCiphertext(data) || bytes.HasPrefix(data, encryptedAssetMagic)) &&
(payloadBoxID == "" || !IsEncryptedBox(payloadBoxID)) {
err = errors.New("encrypted repository data is missing valid notebook context")
return
}
if strings.HasSuffix(file.Path, ".sy") {
// 加密笔记本的 .sy 在仓库里是密文,按路径提取 boxID 解密
data, err = decryptRepoDataIfNeeded(data, file.Path)
if err != nil {
return
}
luteEngine := NewLute()
var snapshotTree *parse.Tree
displayInText, snapshotTree, err = parseTreeInSnapshot(data, luteEngine)
if err != nil {
logging.LogErrorf("parse tree from snapshot file [%s] failed", fileID)
return
}
title = snapshotTree.Root.IALAttr("title")
View on GitHub (pinned to 251596fc0d)
Solutions
- Check the kernel log for the file.Path that triggered it and confirm the leading path segment is a valid 20-char boxID that still exists.
- If the notebook was deleted, the ciphertext is orphaned — remove/ignore that snapshot object; do not attempt to force-decrypt.
- Restore the missing notebook's .siyuan/conf.json (with Encrypted=true) so IsEncryptedBox(payloadBoxID) returns true and the decrypt path engages.
- Recover from an earlier intact snapshot index if the repo store is inconsistent.
Defensive patterns
Strategy: validation
Validate before calling
// Validate the snapshot file path carries a real encrypted boxID before opening
parts := strings.SplitN(strings.TrimPrefix(file.Path, "/"), "/", 2)
if (util.IsCiphertext(data) || bytes.HasPrefix(data, encryptedAssetMagic)) {
if len(parts) < 2 || !ast.IsNodeIDPattern(parts[0]) || !model.IsEncryptedBox(parts[0]) {
return errors.New("encrypted snapshot object has no decryptable notebook context")
}
} Prevention
- Never strip path prefixes from repo objects; the leading boxID segment drives decryption.
- Keep notebook conf.json consistent with the encryption flag of objects that reference it.
- Run repo consistency checks after manual workspace edits.
When it happens
Trigger: Opening a snapshot file whose stored path is malformed (no leading /<boxID>/) yet whose bytes are ciphertext; or an encrypted box that was unregistered/its conf.json removed while ciphertext objects still reference it.
Common situations: Repository store inconsistency after manual editing, a botched notebook deletion that left ciphertext objects, or cross-workspace copying of a repo store whose notebook IDs do not exist in the target workspace.
Related errors
- encrypted repository data is missing notebook context
- encrypted repository data has no matching notebook [%s]
- no such file or directory: %s
- encrypted .sy [%s]: base id [%s] != root id [%s]
- encrypted attribute view snapshot is missing notebook contex
AI-assisted analysis of siyuan-note/siyuan@251596fc0d (2026-08-12).
Data as JSON: /api/errors/3758df93da12965d.
Report an issue: GitHub.