siyuan-note/siyuan · error

encrypted attribute view snapshot has no matching notebook [

Error message

encrypted attribute view snapshot has no matching notebook [%s]

What it means

Thrown by decryptHistoricalAttributeView when a boxID was inferred from the path (so the file lives under a notebook directory) but that notebook is not registered as encrypted (IsEncryptedBox returns false), while the file content is ciphertext. The notebook's encryption context does not match the encrypted payload, so no key is available.

Source

Thrown at kernel/model/attribute_view_render.go:1268

	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

  1. Verify the notebook is actually encrypted via the notebook settings; if it was decrypted, run the migration so its AV files are decrypted too.
  2. Confirm the boxID segment in the path is a real notebook ID and not a coincidental directory name.
  3. If the notebook was never encrypted, the ciphertext file is orphaned; restore a known-good plaintext copy from backup.
Defensive patterns

Strategy: try-catch

Validate before calling

// If you control the path, confirm the notebook is actually encrypted before relying on it.
if boxID != "" && ciphertext && !model.IsEncryptedBox(boxID) {
    // encryption metadata out of sync; do not attempt decrypt
}

Try / catch

data, err := decryptHistoricalAttributeView(boxID, avID, data)
if err != nil {
    if strings.Contains(err.Error(), "no matching notebook") {
        // notebook not encrypted but file is; reconcile encryption state
    }
    return err
}

Prevention

When it happens

Trigger: An AV file sits under /<boxID>/storage/av/ and is encrypted, but the notebook <boxID> is not in the encrypted set. Occurs after a notebook was unencrypted but its AV files were left encrypted, or when a path segment that looks like a boxID is not actually a tracked encrypted notebook.

Common situations: Notebook encryption was disabled/removed without re-encrypting or migrating stored objects; or a repo/history path was rewritten so a non-notebook segment is mistaken for a boxID. The encryption metadata and the on-disk object are out of sync.

Related errors


AI-assisted analysis of siyuan-note/siyuan@251596fc0d (2026-08-12). Data as JSON: /api/errors/2249ef25694882f6. Report an issue: GitHub.