{"record":{"id":"db2c4243d671414b","repo":"siyuan-note/siyuan","slug":"backup-failed-the-cloud-can-only-support-backup-up-to-12","errorCode":null,"errorMessage":"Backup failed: The cloud can only support backup up to 12 snapshots","messagePattern":"Backup failed: The cloud can only support backup up to 12 snapshots","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"kernel/model/repository.go","lineNumber":1545,"sourceCode":"\tswitch Conf.Sync.Provider {\n\tcase conf.ProviderSiYuan:\n\t\tif !IsSubscriber() {\n\t\t\tutil.PushErrMsg(Conf.Language(29), 5000)\n\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","sourceCodeStart":1527,"sourceCodeEnd":1563,"githubUrl":"https://github.com/siyuan-note/siyuan/blob/9f775e8a12daef8255556097396f9b2739078892/kernel/model/repository.go#L1527-L1563","documentation":"UploadCloudSnapshot uploads a tagged snapshot to SiYuan Cloud via the dejavu sync engine. When the cloud account already holds the maximum of 12 backup snapshots, dejavu returns ErrCloudBackupCountExceeded and the kernel translates it into the localized message from Conf.Language(154) wrapped by the 'Backup failed: %s' template (Language 84). It is a deliberate quota guard on the cloud storage service, not a transient failure.","triggerScenarios":"Calling UploadCloudSnapshot (exposed as the API/kernel handler for cloud backup of a snapshot tag) when the cloud workspace already stores 12 snapshots, so dejavu's UploadTagIndex aborts with ErrCloudBackupCountExceeded before uploading.","commonSituations":"Users on the free SiYuan Cloud tier who repeatedly create cloud backups without deleting old ones; automated backup scripts that tag snapshots on every run until the 12-snapshot ceiling is reached; after downgrading a subscription that previously allowed more snapshots.","solutions":["Open the cloud sync snapshots list (Data history / Cloud backups UI) and delete old cloud snapshots until fewer than 12 remain, then retry the backup","Call RemoveCloudRepoTag / removeCloudRepoDir for obsolete tags via the API to free quota slots","Upgrade the SiYuan Cloud subscription if more than 12 cloud snapshots are genuinely needed","Check the returned error for dejavu.ErrCloudBackupCountExceeded before treating it as a generic failure, so quota errors are handled distinctly from network errors"],"exampleFix":"// before\nerr := model.UploadCloudSnapshot(tag, id)\nif err != nil {\n    log.Fatalf(\"backup failed: %v\", err)\n}\n// after\nerr := model.UploadCloudSnapshot(tag, id)\nif err != nil {\n    if strings.Contains(err.Error(), \"only support backup up to 12 snapshots\") {\n        // free quota: list and remove old cloud tags first, then retry\n        removeOldestCloudTag()\n        err = model.UploadCloudSnapshot(tag, id)\n    }\n    if err != nil {\n        log.Fatalf(\"backup failed: %v\", err)\n    }\n}","handlingStrategy":"try-catch","validationCode":"// client-side quota pre-check: keep a count of cloud snapshots before uploading\nconst logs = await fetchPost('/api/repo/getCloudRepoSnapshots', {page: 1});\nif (logs.data.totalCount >= 12) {\n    throw new Error('Cloud snapshot limit reached (12); delete old snapshots first');\n}","typeGuard":null,"tryCatchPattern":"try {\n    await fetchPost('/api/repo/uploadCloudSnapshot', {tag, id});\n} catch (e) {\n    if (e.msg && e.msg.includes('12 snapshots')) {\n        // quota: prompt user to delete old cloud snapshots, not a retryable network error\n    }\n}","preventionTips":["Track cloud snapshot count and delete old tags before creating new cloud backups","Automate periodic cleanup of obsolete cloud snapshot tags","Distinguish quota errors (ErrCloudBackupCountExceeded) from network errors in error handling code","Upgrade the cloud plan if 12 snapshots are insufficient for your backup cadence"],"tags":["cloud","quota","backup","sync","snapshot-limit"],"backgroundTag":"cloud-storage-quota-exceeded","analyzedSha":"9f775e8a12daef8255556097396f9b2739078892","analyzedAt":"2026-09-19T03:17:15.984Z","contentChangedAt":"2026-09-19T03:17:15.984Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}