{"record":{"id":"4e0bef139691231a","repo":"siyuan-note/siyuan","slug":"conf-language-84-formatrepoerrormsg-err","errorCode":null,"errorMessage":"Conf.Language(84), formatRepoErrorMsg(err)","messagePattern":"Conf\\.Language\\(84\\), formatRepoErrorMsg\\(err\\)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"kernel/model/repository.go","lineNumber":1536,"sourceCode":"\t\t\treturn\n\t\t}\n\tcase conf.ProviderWebDAV, conf.ProviderS3, conf.ProviderLocal:\n\t\tif !IsPaidUser() {\n\t\t\tutil.PushErrMsg(Conf.Language(214), 5000)\n\t\t\treturn\n\t\t}\n\t}\n\n\tutil.PushEndlessProgress(Conf.Language(116))\n\tdefer util.PushClearProgress()\n\tuploadFileCount, uploadChunkCount, uploadBytes, err := repo.UploadTagIndex(tag, id, map[string]any{eventbus.CtxPushMsg: eventbus.CtxPushMsgToStatusBarAndProgress})\n\tif err != nil {\n\t\tif errors.Is(err, dejavu.ErrCloudBackupCountExceeded) {\n\t\t\terr = fmt.Errorf(Conf.Language(84), Conf.Language(154))\n\t\t\treturn\n\t\t}\n\t\thandleCloudError(err)\n\t\terr = fmt.Errorf(Conf.Language(84), formatRepoErrorMsg(err))\n\t\treturn\n\t}\n\tmsg := fmt.Sprintf(Conf.Language(152), uploadFileCount, uploadChunkCount, humanize.BytesCustomCeil(uint64(uploadBytes), 2))\n\tutil.PushMsg(msg, 5000)\n\tutil.PushStatusBar(msg)\n\treturn\n}\n\nfunc RemoveCloudRepoTag(tag string) (err error) {\n\tassetDownloadSourceMu.RLock()\n\tdefer assetDownloadSourceMu.RUnlock()\n\tif 1 > len(Conf.Repo.Key) {\n\t\terr = errors.New(Conf.Language(26))\n\t\treturn\n\t}\n\n\thandleCloudError := cloudRepoErrorHandler()\n\tdefer func() { handleCloudError(err) }()","sourceCodeStart":1518,"sourceCodeEnd":1554,"githubUrl":"https://github.com/siyuan-note/siyuan/blob/8641553a1f07374001902d3ce773285db1292b2d/kernel/model/repository.go#L1518-L1554","documentation":"Generic failure path of UploadCloudSnapshot: any error from repo.UploadTagIndex that is not ErrCloudBackupCountExceeded is rewrapped as fmt.Errorf(Conf.Language(84), formatRepoErrorMsg(err)) — 'Backup failed: <reason>'. formatRepoErrorMsg (kernel/model/sync.go:824) first HTML-escapes the message, then maps well-known sentinel errors (cloud auth failed, cloud object not found, cloud locked, repo fatal, system time incorrect, deprecated kernel version, cloud check failed, service unavailable, forbidden, too many requests, decrypt failed) to localized text; unknown errors keep their raw text.","triggerScenarios":"uploadCloudSnapshot call fails inside repo.UploadTagIndex due to: cloud authentication failure (wrong/unexpired token), cloud object not found, cloud repo locked by another device, local repo fatal state, wrong system time, outdated kernel version rejected by the server, cloud service unavailable/forbidden/rate-limited (429), or snapshot decryption failures.","commonSituations":"Expired SiYuan cloud session token; another device holding the cloud lock during upload; machine clock skewed breaking TLS/cloud signatures; running an old kernel against a newer cloud API; transient 5xx or 429 responses from the cloud service; network interruption mid-upload.","solutions":["Read the mapped sub-message in the error to identify the cause; for auth failures re-login to the SiYuan account in Settings - Account, for lock errors wait for the other device to release or remove the lock","Fix the system clock (enable NTP) if time-incorrect is reported, and upgrade SiYuan if a deprecated-version message appears","Check cloud service status / network connectivity, then retry the upload; for 429 responses wait before retrying"],"exampleFix":"// before: blind retry loop\nfor {\n  await fetchPost('/api/repo/uploadCloudSnapshot', {tag, id}); // may keep failing\n}\n// after: inspect and handle mapped causes\ntry {\n  await fetchPost('/api/repo/uploadCloudSnapshot', {tag, id});\n} catch (e) {\n  if (/expired|auth/i.test(e.message)) { await relogin(); }\n  else if (/locked/i.test(e.message)) { await releaseLockOnOtherDevice(); }\n  else { await sleep(backoff); await retry(); }\n}","handlingStrategy":"try-catch","validationCode":"const health = await fetch('https://siyuan-cloud-status-endpoint'); // or ping via ListCloudSyncDir before bulk uploads","typeGuard":"function mapRepoError(err) {\n  if (/auth|expired/i.test(err.message)) return 'auth-failed';\n  if (/locked/i.test(err.message)) return 'cloud-locked';\n  if (/time/i.test(err.message)) return 'system-time';\n  if (/version|deprecated/i.test(err.message)) return 'kernel-outdated';\n  return 'transient';\n}","tryCatchPattern":"try {\n  await fetchPost('/api/repo/uploadCloudSnapshot', {tag, id});\n} catch (e) {\n  const kind = mapRepoError(e);\n  if (kind === 'transient') { await sleep(backoffMs); return retry(); }\n  showError(e.message); // auth/lock/time/version need user action\n}","preventionTips":["Keep the SiYuan cloud session valid (re-login when tokens expire)","Enable NTP so system time skew does not break cloud calls","Keep the kernel updated to avoid deprecated-version rejections from the cloud","Back off and retry on 429/transient cloud errors instead of tight retry loops"],"tags":["cloud-backup","network","api-error","siyuan"],"backgroundTag":"api-error-response","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"}