{"record":{"id":"8eadcb0f47facc88","repo":"siyuan-note/siyuan","slug":"conf-sync-stat","errorCode":null,"errorMessage":"Conf.Sync.Stat","messagePattern":"Conf\\.Sync\\.Stat","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"kernel/model/sync.go","lineNumber":240,"sourceCode":"// SyncDataBeforeEnableEncryptedNotebook 在启用加密笔记本前执行一次完整同步。\n// 未启用数据同步时直接返回；已启用数据同步时，任何同步失败都会阻止继续创建新的密钥体系。\nfunc SyncDataBeforeEnableEncryptedNotebook() error {\n\tif !Conf.Sync.Enabled {\n\t\treturn nil\n\t}\n\tif !cloud.IsValidCloudDirName(Conf.Sync.CloudName) {\n\t\treturn errors.New(Conf.Language(123))\n\t}\n\tif !checkSync(false, false, true) {\n\t\treturn errors.New(Conf.Language(53))\n\t}\n\n\t// 不复用请求合并状态，确保调用返回前确实完成了一次由当前启用操作发起的完整同步。\n\tlockSync()\n\tdefer unlockSync()\n\tif err := syncDataLocked(false, true); err != nil {\n\t\tif Conf.Sync.Stat != \"\" {\n\t\t\treturn errors.New(Conf.Sync.Stat)\n\t\t}\n\t\treturn err\n\t}\n\treturn nil\n}\n\nfunc lockSync() {\n\tsyncLock.Lock()\n\tisSyncing.Store(true)\n}\n\nfunc unlockSync() {\n\tisSyncing.Store(false)\n\tsyncLock.Unlock()\n}\n\ntype syncRequestState struct {\n\trequested atomic.Uint64","sourceCodeStart":222,"sourceCodeEnd":258,"githubUrl":"https://github.com/siyuan-note/siyuan/blob/251596fc0de2f9528c00c224252fd073a99973f4/kernel/model/sync.go#L222-L258","documentation":"When syncDataLocked returns an error during the encryption-enable prerequisite sync, SyncDataBeforeEnableEncryptedNotebook returns Conf.Sync.Stat verbatim if it is non-empty. Conf.Sync.Stat holds the human-readable status string written by the sync engine (e.g. 'network error', 'auth failed', 'index corrupt'), so the caller sees the real cause rather than a generic message. If Stat is empty, the raw error is returned instead.","triggerScenarios":"The actual sync round fails after lockSync(): network/timeout talking to S3/WebDAV/cloud, authentication rejected, cloud lock contention (dejavu ErrLockCloudFailed), index fatal error, or system time incorrect. Any of these sets Conf.Sync.Stat and surfaces here.","commonSituations":"Cloud token expired. S3 endpoint unreachable / wrong region. WebDAV credentials changed. Two clients syncing concurrently and the cloud is locked by the other. Disk full or index corruption mid-sync.","solutions":["Read Conf.Sync.Stat / the UI sync status banner for the specific cause and address it (re-login, fix endpoint, free disk).","Retry the encryption-enable once the underlying sync succeeds (run Sync now manually and confirm it reports success).","If Stat points to a cloud lock, wait for the other client to finish or force-release per dejavu docs."],"exampleFix":"// runtime error, not a code bug\n// before: enable encryption -> sync fails with Stat='network error'\n// after: resolve network/provider issue, sync succeeds, then enable","handlingStrategy":"try-catch","validationCode":"// Cannot fully pre-validate network outcomes, but can preflight:\nif !syncRunnable() { return errors.New(\"sync not runnable\") }","typeGuard":null,"tryCatchPattern":"// Go caller (e.g. crypto.go enable flow)\nif err := model.SyncDataBeforeEnableEncryptedNotebook(); err != nil {\n    logging.LogErrorf(\"prerequisite sync failed: %s\", err)\n    return err // surface Stat to the user, do not proceed to key creation\n}","preventionTips":["Always run a manual sync before enabling encryption so Stat is clean.","Treat a non-empty Conf.Sync.Stat as a hard stop for the enable action.","Log the full Stat string; it carries the actionable root cause."],"tags":["sync","crypto","encryption","cloud","kernel","runtime","network"],"backgroundTag":null,"analyzedSha":"251596fc0de2f9528c00c224252fd073a99973f4","analyzedAt":"2026-08-12T21:18:37.123Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}