{"record":{"id":"736cef917e3a0899","repo":"siyuan-note/siyuan","slug":"encrypted-attribute-view-snapshot-is-missing-noteb","errorCode":null,"errorMessage":"encrypted attribute view snapshot is missing notebook context","messagePattern":"encrypted attribute view snapshot is missing notebook context","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"kernel/model/attribute_view_render.go","lineNumber":1262,"sourceCode":"\n\tattrView = av.NewAttributeView(avID)\n\tif err = gulu.JSON.UnmarshalJSON(data, attrView); err != nil {\n\t\tlogging.LogErrorf(\"unmarshal attribute view [%s] failed: %s\", avID, err)\n\t\treturn\n\t}\n\tif err = av.CheckSpec(attrView); nil != err {\n\t\treturn\n\t}\n\n\tviewable, err = renderAttributeView(attrView, \"\", viewID, carrierViewID, query, page, pageSize, groupPaging, false, false, nil, \"\")\n\treturn\n}\n\nfunc decryptHistoricalAttributeView(boxID, avID string, data []byte) ([]byte, error) {\n\tciphertext := util.IsCiphertext(data)\n\tif boxID == \"\" {\n\t\tif ciphertext {\n\t\t\treturn nil, errors.New(\"encrypted attribute view snapshot is missing notebook context\")\n\t\t}\n\t\treturn data, nil\n\t}\n\tif !IsEncryptedBox(boxID) {\n\t\tif ciphertext {\n\t\t\treturn nil, fmt.Errorf(\"encrypted attribute view snapshot has no matching notebook [%s]\", boxID)\n\t\t}\n\t\treturn data, nil\n\t}\n\tif !ciphertext {\n\t\treturn nil, fmt.Errorf(\"encrypted notebook attribute view snapshot is plaintext [%s]\", boxID)\n\t}\n\treturn av.DecryptAVData(boxID, avID, data)\n}\n","sourceCodeStart":1244,"sourceCodeEnd":1277,"githubUrl":"https://github.com/siyuan-note/siyuan/blob/251596fc0de2f9528c00c224252fd073a99973f4/kernel/model/attribute_view_render.go#L1244-L1277","documentation":"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.","triggerScenarios":"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).","commonSituations":"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.","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."],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"data, err := decryptHistoricalAttributeView(boxID, avID, data)\nif err != nil {\n    if err.Error() == \"encrypted attribute view snapshot is missing notebook context\" {\n        // AV is encrypted but its notebook context was lost; restore correct path or skip\n    }\n    return err\n}","preventionTips":["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."],"tags":["attribute-view","encryption","data-integrity","notebook-context"],"backgroundTag":null,"analyzedSha":"251596fc0de2f9528c00c224252fd073a99973f4","analyzedAt":"2026-08-12T21:18:37.123Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}