siyuan-note/siyuan · error

376

376

Error message

Conf.Language(376)

What it means

checkAssetDownloadAccess gates on-demand asset download behind sync: sync must be enabled, the user must be logged in, and per provider the account must qualify (SiYuan provider: subscriber; S3/WebDAV/Local: paid user). Failing the first gate returns i18n message 376 ('The asset has not been downloaded and cannot be retrieved right now').

Solutions

  1. Enable cloud sync in Settings - Sync and log in, then retry the asset access
  2. Re-authenticate if the login session expired so Conf.GetUser() returns a user
  3. If you do not need cloud asset download, download assets via full sync ('Download all') instead
  4. For API-driven setups, ensure the request is made after sync is initialized rather than at boot
Defensive patterns

Strategy: validation

Validate before calling

const user = await fetchPost("/api/user/getCloudUser", {});
const syncEnabled = (await fetchPost("/api/sync/getSyncInfo", {})).enabled;
if (!syncEnabled || !user?.userId) throw new Error("enable sync and log in before downloading assets");

Type guard

const canDownloadAssets = (s, u) => Boolean(s && s.enabled && u && u.userId);

Try / catch

try {
  await ensureAssetLocal(assetPath);
} catch (e) {
  if (String(e).includes(Conf.Language(376))) {
    // surface 'enable sync / log in' UI before retrying
  }
}

Prevention

When it happens

Trigger: EnsureAssetLocal, EnsureAssetPrefixLocal, ensureAllSyncAssets, SetSyncAssetDownloadMode, or openRepoFileWithAssets runs while Conf.Sync is nil or disabled, or Conf.GetUser() is nil (not logged in).

Common situations: Cloud sync disabled in settings while a missing asset is requested; session expired so the user object is nil; automation/script tries to fetch assets offline without sync configured.

Related errors


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

Appendix: source

Thrown at kernel/model/asset_download.go:100

// validateAssetDownloadSourceScope 在公布新的账号身份前保留未完成的资源与历史恢复来源。
func validateAssetDownloadSourceScope(scope string) error {
	exists, err := assetDownloadStateExists()
	if err != nil || !exists {
		return err
	}
	if Conf.Repo == nil || len(Conf.Repo.Key) == 0 {
		return errors.New(Conf.Language(377))
	}
	stored, err := dejavu.ReadAssetDownloadScope(assetDownloadStatePath(), Conf.Repo.Key)
	if err != nil || stored == scope {
		return err
	}
	return requireCompleteAssetDownloads()
}

func checkAssetDownloadAccess() error {
	if Conf.Sync == nil || !Conf.Sync.Enabled || Conf.GetUser() == nil {
		return errors.New(Conf.Language(376))
	}
	switch Conf.Sync.Provider {
	case conf.ProviderSiYuan:
		if !IsSubscriber() {
			return errors.New(Conf.Language(376))
		}
	case conf.ProviderS3, conf.ProviderWebDAV, conf.ProviderLocal:
		if !IsPaidUser() {
			return errors.New(Conf.Language(376))
		}
	}
	return nil
}

func dataRelativeAssetPath(absPath string) (string, error) {
	if !filepath.IsAbs(absPath) {
		return "", fmt.Errorf("asset path must be absolute")
	}

View on GitHub (pinned to 9f775e8a12)