siyuan-note/siyuan · error

Backup failed: The cloud can only support backup up to 12…

Error message

Backup failed: The cloud can only support backup up to 12 snapshots

What it means

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.

Solutions

  1. 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
  2. Call RemoveCloudRepoTag / removeCloudRepoDir for obsolete tags via the API to free quota slots
  3. Upgrade the SiYuan Cloud subscription if more than 12 cloud snapshots are genuinely needed
  4. Check the returned error for dejavu.ErrCloudBackupCountExceeded before treating it as a generic failure, so quota errors are handled distinctly from network errors

Example fix

// before
err := model.UploadCloudSnapshot(tag, id)
if err != nil {
    log.Fatalf("backup failed: %v", err)
}
// after
err := model.UploadCloudSnapshot(tag, id)
if err != nil {
    if strings.Contains(err.Error(), "only support backup up to 12 snapshots") {
        // free quota: list and remove old cloud tags first, then retry
        removeOldestCloudTag()
        err = model.UploadCloudSnapshot(tag, id)
    }
    if err != nil {
        log.Fatalf("backup failed: %v", err)
    }
}
Defensive patterns

Strategy: try-catch

Validate before calling

// client-side quota pre-check: keep a count of cloud snapshots before uploading
const logs = await fetchPost('/api/repo/getCloudRepoSnapshots', {page: 1});
if (logs.data.totalCount >= 12) {
    throw new Error('Cloud snapshot limit reached (12); delete old snapshots first');
}

Try / catch

try {
    await fetchPost('/api/repo/uploadCloudSnapshot', {tag, id});
} catch (e) {
    if (e.msg && e.msg.includes('12 snapshots')) {
        // quota: prompt user to delete old cloud snapshots, not a retryable network error
    }
}

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Related errors


AI-assisted analysis of siyuan-note/siyuan@9f775e8a12 (2026-09-19). Data as JSON: /api/errors/db2c4243d671414b. Report an issue: GitHub.

Appendix: source

Thrown at kernel/model/repository.go:1545

	switch Conf.Sync.Provider {
	case conf.ProviderSiYuan:
		if !IsSubscriber() {
			util.PushErrMsg(Conf.Language(29), 5000)
			return
		}
	case conf.ProviderWebDAV, conf.ProviderS3, conf.ProviderLocal:
		if !IsPaidUser() {
			util.PushErrMsg(Conf.Language(214), 5000)
			return
		}
	}

	util.PushEndlessProgress(Conf.Language(116))
	defer util.PushClearProgress()
	uploadFileCount, uploadChunkCount, uploadBytes, err := repo.UploadTagIndex(tag, id, map[string]any{eventbus.CtxPushMsg: eventbus.CtxPushMsgToStatusBarAndProgress})
	if err != nil {
		if errors.Is(err, dejavu.ErrCloudBackupCountExceeded) {
			err = fmt.Errorf(Conf.Language(84), Conf.Language(154))
			return
		}
		handleCloudError(err)
		err = fmt.Errorf(Conf.Language(84), formatRepoErrorMsg(err))
		return
	}
	msg := fmt.Sprintf(Conf.Language(152), uploadFileCount, uploadChunkCount, humanize.BytesCustomCeil(uint64(uploadBytes), 2))
	util.PushMsg(msg, 5000)
	util.PushStatusBar(msg)
	return
}

func RemoveCloudRepoTag(tag string) (err error) {
	assetDownloadSourceMu.RLock()
	defer assetDownloadSourceMu.RUnlock()
	if 1 > len(Conf.Repo.Key) {
		err = errors.New(Conf.Language(26))
		return

View on GitHub (pinned to 9f775e8a12)