siyuan-note/siyuan · error

encrypted snapshot document is missing valid notebook contex

Error message

encrypted snapshot document is missing valid notebook context

What it means

A ciphertext snapshot document must map to a valid encrypted notebook via its repo path (first path segment being a node-ID-pattern box ID of an encrypted notebook) so the right DEK can be used. This error means the ciphertext file's path lacks a usable notebook context — wrong number of segments, malformed box ID, or box not registered as encrypted.

Source

Thrown at kernel/model/history_diff.go:424

		return nil, err
	}
	file, err := repo.GetFile(fileID)
	if err != nil {
		return nil, err
	}
	if !strings.HasSuffix(strings.ToLower(file.Path), ".sy") {
		return nil, errors.New("snapshot version is not a document")
	}
	repoPath := strings.TrimPrefix(file.Path, "/")
	pathParts := strings.SplitN(repoPath, "/", 2)
	data, err := repo.OpenFile(file)
	if err != nil {
		return nil, err
	}
	ciphertext := util.IsCiphertext(data)
	if ciphertext {
		if len(pathParts) < 2 || !ast.IsNodeIDPattern(pathParts[0]) || !IsEncryptedBox(pathParts[0]) {
			return nil, errors.New("encrypted snapshot document is missing valid notebook context")
		}
		HoldBoxReadLock(pathParts[0])
		defer ReleaseBoxReadLock(pathParts[0])
		dek, unlockErr := GetDEKIfUnlocked(pathParts[0])
		if unlockErr != nil {
			return nil, errors.New(Conf.Language(314))
		}
		data, err = DecryptFile(pathParts[0], pathParts[1], dek, data)
		if err != nil {
			return nil, err
		}
	} else if len(pathParts) > 0 && IsEncryptedBox(pathParts[0]) {
		return nil, fmt.Errorf("encrypted notebook snapshot document is plaintext [%s]", pathParts[0])
	}
	rootID := strings.TrimSuffix(filepath.Base(file.Path), filepath.Ext(file.Path))
	tree, err := parseDocVersionTree(data, rootID)
	boxID := ""
	if 0 < len(pathParts) && ast.IsNodeIDPattern(pathParts[0]) {

View on GitHub (pinned to 8641553a1f)

Solutions

  1. Ensure the snapshot path is /<boxID>/<docPath>.sy with a valid encrypted notebook ID
  2. Confirm the notebook still exists and is registered encrypted (IsEncryptedBox)
  3. Re-snapshot or re-import the document into a valid encrypted notebook
Defensive patterns

Strategy: validation

Validate before calling

const segs = filePath.replace(/^\//, "").split("/"); if (segs.length < 2 || !isNodeID(segs[0]) || !isEncryptedBox(segs[0])) throw new Error("no valid encrypted notebook context");

Type guard

const hasEncBoxCtx = (path: string) => { const s = path.replace(/^\//, "").split("/"); return s.length >= 2 && /^[0-9]{14}-[0-9a-z]{7}$/.test(s[0]); };

Try / catch

try { await api.loadDocVersion(fileID); } catch (e) { if (String(e).includes("missing valid notebook context")) { showToast("Snapshot path has no encrypted notebook context"); } }

Prevention

When it happens

Trigger: Opening a ciphertext snapshot whose repo path has fewer than 2 segments, whose first segment is not a valid node-ID notebook ID, or whose box is not an encrypted notebook.

Common situations: Snapshot files relocated outside the expected /<boxID>/<docPath> layout; notebook deleted or converted to non-encrypted after the snapshot was taken; manually crafted repo file paths.

Understand the failure class

Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.

Related errors


AI-assisted analysis of siyuan-note/siyuan@8641553a1f (2026-09-11). Data as JSON: /api/errors/97f9b54598edafa8. Report an issue: GitHub.