{"record":{"id":"d4cf471d6e597d1b","repo":"siyuan-note/siyuan","slug":"conf-language-314-d4cf47","errorCode":null,"errorMessage":"Conf.Language(314)","messagePattern":"Conf\\.Language\\(314\\)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"kernel/model/encrypted_export.go","lineNumber":242,"sourceCode":"\tif !strings.HasPrefix(exportPath, \"assets/\") {\n\t\treturn nil, errors.New(\"unsupported export path\")\n\t}\n\trelativePath, boxID, parseErr := assetPathAndBox(exportPath, \"\")\n\tif parseErr != nil {\n\t\treturn nil, parseErr\n\t}\n\tif boxID == \"\" || !IsEncryptedBox(boxID) {\n\t\tartifact, resolveErr := GetAssetAbsPath(relativePath)\n\t\tif resolveErr != nil {\n\t\t\treturn nil, resolveErr\n\t\t}\n\t\tif ensureErr := EnsureAssetLocal(artifact); ensureErr != nil {\n\t\t\treturn nil, ensureErr\n\t\t}\n\t\treturn registerMobileExportLease(\"\", artifact, filepath.Base(artifact), \"\")\n\t}\n\tif !IsBoxUnlocked(boxID) {\n\t\treturn nil, errors.New(Conf.Language(314))\n\t}\n\tartifact, resolveErr := GetAssetAbsPathInBox(relativePath, boxID)\n\tif resolveErr != nil {\n\t\treturn nil, resolveErr\n\t}\n\tif ensureErr := EnsureAssetLocal(artifact); ensureErr != nil {\n\t\treturn nil, ensureErr\n\t}\n\n\tif err = AcquireEncryptedBoxOperation(boxID); err != nil {\n\t\treturn nil, err\n\t}\n\tHoldBoxReadLock(boxID)\n\trelease := true\n\tdefer func() {\n\t\tif release {\n\t\t\tReleaseBoxReadLock(boxID)\n\t\t\tReleaseEncryptedBoxOperation(boxID)","sourceCodeStart":224,"sourceCodeEnd":260,"githubUrl":"https://github.com/siyuan-note/siyuan/blob/8641553a1f07374001902d3ce773285db1292b2d/kernel/model/encrypted_export.go#L224-L260","documentation":"When the asset referenced by exportPath belongs to an encrypted notebook, AcquireExportArtifactLease requires that the notebook be unlocked before it can resolve the asset path with the box DEK and register the lease. If the box is still locked, the function aborts with the localized message Conf.Language(314) (\"the encrypted notebook is locked / must be unlocked\"). This is an authentication/state precondition, not a data error.","triggerScenarios":"Calling AcquireExportArtifactLease (via materializeExportArtifact or AcquireMobileExportLease) with exportPath = \"assets/<file>\" where assetPathAndBox resolves the asset to an encrypted box (IsEncryptedBox(boxID) true) and IsBoxUnlocked(boxID) is false — i.e. the user has not supplied the passphrase or the box was re-locked.","commonSituations":"Background export/sync jobs running after the app restarted (boxes locked at boot); a mobile export request racing with the user locking the box; automated scripts that never unlocked the encrypted notebook; box auto-lock timeout elapsed before export.","solutions":["Unlock the encrypted notebook first (call the box unlock API / prompt the user for the passphrase), then retry AcquireExportArtifactLease.","Check IsBoxUnlocked(boxID) before requesting the lease and defer export until the box is unlocked.","For automated flows, keep the box unlocked for the duration of the export and register the lease promptly after unlocking (leases also hold a box read lock)."],"exampleFix":"// before\nlease, err := model.AcquireExportArtifactLease(exportPath)\n// after\nif _, boxID, perr := model.AssetPathAndBox(exportPath); perr == nil && !model.IsBoxUnlocked(boxID) {\n    if uerr := model.UnlockBox(boxID, passphrase); uerr != nil { return uerr }\n}\nlease, err := model.AcquireExportArtifactLease(exportPath)","handlingStrategy":"try-catch","validationCode":"if boxID != \"\" && model.IsEncryptedBox(boxID) && !model.IsBoxUnlocked(boxID) {\n    // prompt for passphrase / unlock first\n}","typeGuard":null,"tryCatchPattern":"lease, err := model.AcquireExportArtifactLease(exportPath)\nif err != nil {\n    if isBoxLockedError(err) { // localized Conf.Language(314)\n        if uerr := unlockBoxAndRetry(exportPath); uerr == nil {\n            lease, err = model.AcquireExportArtifactLease(exportPath)\n        }\n    }\n    if err != nil { return err }\n}","preventionTips":["Check IsBoxUnlocked before any encrypted-box export flow","Handle app restart: boxes start locked, unlock before background exports","Keep export flows in the foreground so users can answer passphrase prompts"],"tags":["encryption","locked-notebook","export"],"backgroundTag":"authentication-required","analyzedSha":"8641553a1f07374001902d3ce773285db1292b2d","analyzedAt":"2026-09-11T16:08:28.414Z","contentChangedAt":"2026-09-11T16:08:28.414Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}