{"record":{"id":"1c642ab9fc30f0f7","repo":"siyuan-note/siyuan","slug":"related-operations-are-being-processed-please-try","errorCode":null,"errorMessage":"Related operations are being processed, please try again later","messagePattern":"Related operations are being processed, please try again later","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"kernel/model/crypto.go","lineNumber":1371,"sourceCode":"\tnotebookCryptoMu.Lock()\n\tdefer notebookCryptoMu.Unlock()\n\treleaseTransition := holdEncryptedBoxTransition(boxID)\n\tdefer releaseTransition()\n\n\twasUnlocked := IsBoxUnlocked(boxID)\n\tif err = unlockBoxHeld(boxID, password, boxEnc); err != nil {\n\t\treturn false, err\n\t}\n\talreadyMount, err = mountBox(boxID)\n\tif err != nil && !wasUnlocked {\n\t\tlockBoxWithPreparationHeld(boxID, nil)\n\t}\n\treturn alreadyMount, err\n}\n\nfunc unlockBoxHeld(boxID string, password string, boxEnc *conf.BoxEncryption) (err error) {\n\tif _, busy := boxLock.Load(boxID); busy {\n\t\treturn errors.New(Conf.language(239))\n\t}\n\tif boxEnc == nil || len(boxEnc.WrappedDEK) == 0 {\n\t\tsetEncryptedBoxState(boxID, EncryptedBoxStateError)\n\t\treturn errors.New(\"no encrypted key material for box\")\n\t}\n\tif IsBoxUnlocked(boxID) {\n\t\tif GetEncryptedBoxState(boxID) == EncryptedBoxStateError {\n\t\t\treturn errors.New(Conf.Language(316))\n\t\t}\n\t\tsetEncryptedBoxState(boxID, EncryptedBoxStateUnlocked)\n\t\treturn nil\n\t}\n\n\tsetEncryptedBoxState(boxID, EncryptedBoxStateUnlocking)\n\t// 获取 box 写锁，与 LockBox/unmount0 串行化，防止并发锁/解锁导致 db/DEK 状态不一致\n\tacquireBoxWriteLock(boxID)\n\tfinalState := EncryptedBoxStateLocked\n\tdefer func() {","sourceCodeStart":1353,"sourceCodeEnd":1389,"githubUrl":"https://github.com/siyuan-note/siyuan/blob/251596fc0de2f9528c00c224252fd073a99973f4/kernel/model/crypto.go#L1353-L1389","documentation":"Thrown by unlockBoxHeld (crypto.go:1371, i18n code 239) when boxLock already has an entry for this boxID, meaning another mount/unmount/history operation is currently in progress on that notebook. This is a transient concurrency guard: the requested unlock cannot proceed in parallel with the in-flight operation and the caller should retry shortly. Unlike the transition lock (holdEncryptedBoxTransition, which blocks waiting), this busy flag fails fast.","triggerScenarios":"unlockBoxHeld is called (via UnlockBox or UnlockAndMountBox) while boxLock.LoadOrStore for the same boxID is held by mountBox, unmount0, or a history operation (mount.go / history.go). E.g. user double-clicks unlock while a mount is mid-flight, or a sync-triggered remount overlaps a manual unlock.","commonSituations":"Rapid repeated unlock clicks. Concurrent sync/export touching the same notebook. UI retry storm during slow Argon2id derivation on the same box.","solutions":["Retry the unlock after the in-flight operation completes (this is the intended handling; the error is transient).","Debounce/disable the unlock button in the UI until the current operation returns to prevent repeated triggers.","Avoid calling UnlockBox/UnlockAndMountBox concurrently for the same notebook from multiple paths."],"exampleFix":null,"handlingStrategy":"retry","validationCode":null,"typeGuard":null,"tryCatchPattern":"// Transient busy state: back off and retry a few times.\nconst maxRetries = 5\nfor i := 0; i < maxRetries; i++ {\n    err := model.UnlockBox(boxID, password, boxCrypt)\n    if err == nil {\n        break\n    }\n    if err.Error() == model.Conf.Language(239) {\n        time.Sleep(backoff(i)) // exponential backoff\n        continue\n    }\n    return err\n}","preventionTips":["Debounce the unlock button in the UI so rapid clicks do not stack.","Avoid concurrent unlock and sync/export on the same notebook.","Treat code 239 as transient and retry with backoff, not as a hard failure."],"tags":["encryption","notebook-crypto","concurrency","retry","transient"],"backgroundTag":null,"analyzedSha":"251596fc0de2f9528c00c224252fd073a99973f4","analyzedAt":"2026-08-12T21:18:37.123Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}