siyuan-note/siyuan · error
encrypted attribute view snapshot is missing notebook contex
Error message
encrypted attribute view snapshot is missing notebook context
What it means
Thrown by decryptHistoricalAttributeView when the boxID derived from the file location is empty (global storage path) but the file content is detected as ciphertext by util.IsCiphertext. Decryption needs a notebook's data-encryption key, which can only be looked up by boxID, so an encrypted blob at a global path with no notebook context cannot be decrypted.
Source
Thrown at kernel/model/attribute_view_render.go:1262
attrView = av.NewAttributeView(avID)
if err = gulu.JSON.UnmarshalJSON(data, attrView); err != nil {
logging.LogErrorf("unmarshal attribute view [%s] failed: %s", avID, err)
return
}
if err = av.CheckSpec(attrView); nil != err {
return
}
viewable, err = renderAttributeView(attrView, "", viewID, carrierViewID, query, page, pageSize, groupPaging, false, false, nil, "")
return
}
func decryptHistoricalAttributeView(boxID, avID string, data []byte) ([]byte, error) {
ciphertext := util.IsCiphertext(data)
if boxID == "" {
if ciphertext {
return nil, errors.New("encrypted attribute view snapshot is missing notebook context")
}
return data, nil
}
if !IsEncryptedBox(boxID) {
if ciphertext {
return nil, fmt.Errorf("encrypted attribute view snapshot has no matching notebook [%s]", boxID)
}
return data, nil
}
if !ciphertext {
return nil, fmt.Errorf("encrypted notebook attribute view snapshot is plaintext [%s]", boxID)
}
return av.DecryptAVData(boxID, avID, data)
}
View on GitHub (pinned to 251596fc0d)
Solutions
- Restore the file to its correct notebook-scoped path (/<boxID>/storage/av/<avID>.json) so the boxID can be inferred and the matching key used.
- If the owning notebook is unknown/removed, the data cannot be recovered through this path; restore from a backup that preserves the notebook structure.
- Prevent the migration by ensuring sync/import keeps encrypted-notebook objects under their notebook path.
Defensive patterns
Strategy: try-catch
Try / catch
data, err := decryptHistoricalAttributeView(boxID, avID, data)
if err != nil {
if err.Error() == "encrypted attribute view snapshot is missing notebook context" {
// AV is encrypted but its notebook context was lost; restore correct path or skip
}
return err
} Prevention
- Preserve the notebook-scoped path (/<boxID>/storage/av/<avID>.json) for encrypted-notebook AV files during sync/import/restore.
- Do not move encrypted objects to the global storage location.
- Treat this error as unrecoverable for that object without a backup that preserves notebook structure.
When it happens
Trigger: An encrypted notebook's attribute view file has migrated to the global /storage/av/ location (no leading <boxID> segment) via sync, import, or a layout change. The decryptor sees ciphertext but has no boxID to select the key. Can be reached from RenderRepoSnapshotAttributeView (avBoxIDFromRepoPath returns "") or RenderHistoryAttributeView (source.boxID empty).
Common situations: Encrypted-notebook AV files ending up at global paths after data repo restore, cross-workspace sync where the notebook envelope was not preserved, or history generated before the boxID-path convention was enforced. The data is intact but its owner context was lost.
Related errors
- encrypted attribute view snapshot has no matching notebook [
- encrypted notebook attribute view snapshot is plaintext [%s]
- attribute view history context is ambiguous [%s]
- encrypted notebook metadata verification failed after write
- Encrypted notebooks do not support this operation
AI-assisted analysis of siyuan-note/siyuan@251596fc0d (2026-08-12).
Data as JSON: /api/errors/736cef917e3a0899.
Report an issue: GitHub.