siyuan-note/siyuan · warning
managed export is unavailable
Error message
managed export is unavailable
What it means
When the requested export file name belongs to a managed encrypted export path, `ResolveManagedEncryptedExport` must map it back to a live box/artifact. This error means the name has the managed prefix but no matching managed export registration exists — the artifact record is gone or was never registered.
Source
Thrown at kernel/model/encrypted_export.go:191
}
return filepath.FromSlash(strings.Join(parts, "/"))
}
// AcquireExportArtifactLease 为导出产物取得覆盖整个复制过程的生命周期租约。
func AcquireExportArtifactLease(exportPath string) (lease *ExportArtifactLease, err error) {
if after, ok := strings.CutPrefix(exportPath, "/export/"); ok {
fileName, decodeErr := url.PathUnescape(after)
if decodeErr != nil {
return nil, decodeErr
}
fileName = filepath.Clean(fileName)
if fileName == "." || strings.HasPrefix(fileName, "..") || filepath.IsAbs(fileName) {
return nil, errors.New("invalid export path")
}
if IsManagedEncryptedExportPath(fileName) {
boxID, artifact, resolved := ResolveManagedEncryptedExport(fileName)
if !resolved {
return nil, errors.New("managed export is unavailable")
}
if err = AcquireEncryptedBoxOperation(boxID); err != nil {
return nil, err
}
HoldBoxReadLock(boxID)
release := true
defer func() {
if release {
ReleaseBoxReadLock(boxID)
ReleaseEncryptedBoxOperation(boxID)
}
}()
_, artifact, resolved = ResolveManagedEncryptedExport(fileName)
if !resolved {
return nil, errors.New("managed export is unavailable")
}
if _, dekErr := GetDEKIfUnlocked(boxID); dekErr != nil {
return nil, dekErrView on GitHub (pinned to 8641553a1f)
Solutions
- Re-run the export to produce a fresh managed export path, then request the lease with the new name.
- Verify the source notebook is unlocked — managed resolution requires the box to still be registered.
- Clear the stale reference in the client and re-navigate from the export result instead of a cached URL.
- If this happens right after restart, re-trigger the export since managed registrations are in-memory.
Example fix
// before
leaseFromOldManagedName("export/managed-abc123.html") // stale after restart
// after
const exported = await runExport(boxID) // returns fresh managed name
leaseFromOldManagedName(exported.managedName) Defensive patterns
Strategy: retry
Try / catch
lease, err := model.AcquireExportArtifactLease(name)
if err != nil && err.Error() == "managed export is unavailable" {
// regenerate the export and retry with the fresh managed name
fresh := regenerateExport(boxID)
lease, err = model.AcquireExportArtifactLease(fresh)
} Prevention
- Treat managed export names as ephemeral; re-export after kernel restart.
- Do not cache managed export URLs across sessions.
- Avoid re-locking or cleaning exports while clients still hold managed names.
When it happens
Trigger: AcquireExportArtifactLease called with a managed export path for which ResolveManagedEncryptedExport returns resolved=false (first lookup, before any lease is held).
Common situations: Requesting an export lease for an artifact whose registration expired or was cleared after kernel restart; a client retrying with an old managed file name after the export was regenerated; typo'd managed path.
Understand the failure class
Background: 'Could not be found', 'does not exist', 'not found in database': the resource-not-found family when an ID, slug, key, or URI lookup comes back empty — this error's family across 20 libraries.
Related errors
- Please unlock the encrypted notebook first
- cannot disable encrypted notebook feature while encrypted no
- encrypted box db not opened for box %s
- master password migration is pending
- Please unlock the encrypted notebook first
AI-assisted analysis of siyuan-note/siyuan@8641553a1f (2026-09-11).
Data as JSON: /api/errors/2ac72ee36965310b.
Report an issue: GitHub.