siyuan-note/siyuan · error

Conf.Language(84), formatRepoErrorMsg(err)

Error message

Conf.Language(84), formatRepoErrorMsg(err)

What it means

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.

Source

Thrown at kernel/model/repository.go:1536

			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
	}

	handleCloudError := cloudRepoErrorHandler()
	defer func() { handleCloudError(err) }()

View on GitHub (pinned to 8641553a1f)

Solutions

  1. 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
  2. Fix the system clock (enable NTP) if time-incorrect is reported, and upgrade SiYuan if a deprecated-version message appears
  3. Check cloud service status / network connectivity, then retry the upload; for 429 responses wait before retrying

Example fix

// before: blind retry loop
for {
  await fetchPost('/api/repo/uploadCloudSnapshot', {tag, id}); // may keep failing
}
// after: inspect and handle mapped causes
try {
  await fetchPost('/api/repo/uploadCloudSnapshot', {tag, id});
} catch (e) {
  if (/expired|auth/i.test(e.message)) { await relogin(); }
  else if (/locked/i.test(e.message)) { await releaseLockOnOtherDevice(); }
  else { await sleep(backoff); await retry(); }
}
Defensive patterns

Strategy: try-catch

Validate before calling

const health = await fetch('https://siyuan-cloud-status-endpoint'); // or ping via ListCloudSyncDir before bulk uploads

Type guard

function mapRepoError(err) {
  if (/auth|expired/i.test(err.message)) return 'auth-failed';
  if (/locked/i.test(err.message)) return 'cloud-locked';
  if (/time/i.test(err.message)) return 'system-time';
  if (/version|deprecated/i.test(err.message)) return 'kernel-outdated';
  return 'transient';
}

Try / catch

try {
  await fetchPost('/api/repo/uploadCloudSnapshot', {tag, id});
} catch (e) {
  const kind = mapRepoError(e);
  if (kind === 'transient') { await sleep(backoffMs); return retry(); }
  showError(e.message); // auth/lock/time/version need user action
}

Prevention

When it happens

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

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

Related errors


AI-assisted analysis of siyuan-note/siyuan@8641553a1f (2026-09-11). Data as JSON: /api/errors/4e0bef139691231a. Report an issue: GitHub.