siyuan-note/siyuan · error
377
377
Error message
Conf.Language(377)
What it means
deferredSyncAssets reads the persisted asset-download state to re-list pending asset files, but requires the data repo encryption key (Conf.Repo.Key) to decrypt that state. When no repo key exists, it fails with i18n message 377: the user must switch to 'Download all' before changing or resetting the data repository. The wrapped operation (and any deferred asset completion) is aborted.
Solutions
- Switch sync asset download mode to 'Download all' to clear the pending asset-download state, then re-run the operation
- Re-open/unlock the data repository so Conf.Repo.Key is populated before syncing assets
- Complete or cancel the pending asset download before changing or resetting the repository
- If the state is stale and unrecoverable, remove the asset download state file after backing up the workspace
Defensive patterns
Strategy: try-catch
Validate before calling
// check repo key presence and pending asset-download state before asset operations
const sync = await fetchPost("/api/sync/getSyncInfo", {});
if (!sync.key || sync.assetDownloadStateExists) {
await fetchPost("/api/sync/setSyncAssetDownloadMode", {mode: "download-all"});
} Try / catch
try {
await ensureAssetLocal(path);
} catch (e) {
if (String(e).includes(Conf.Language(377))) {
// prompt user to switch to 'Download all' or re-open the data repo
}
} Prevention
- Finish or cancel pending asset downloads before resetting or re-creating the data repository
- Keep the repo key available (unlock the repository) before running asset sync
- Avoid moving workspaces between machines without repo key material
- Switch to 'Download all' when you plan to change accounts or reset the repo
When it happens
Trigger: EnsureAssetLocal, EnsureAssetPrefixLocal, DeferredSyncAssets, ensureAllSyncAssets, or requireCompleteAssetDownloads runs while a partial asset-download state exists but Conf.Repo is nil or Conf.Repo.Key is empty (repo not opened / key reset).
Common situations: User reset or re-created the data repository while 'Download only modified assets now' mode was active; workspace moved to a machine without the repo key; cloud credential loss cleared the repo key.
Related errors
AI-assisted analysis of siyuan-note/siyuan@9f775e8a12 (2026-09-19).
Data as JSON: /api/errors/a19def4330b88693.
Report an issue: GitHub.
Appendix: source
Thrown at kernel/model/asset_download.go:77
identity = append(identity, filepath.Clean(c.Local.Endpoint))
}
}
data, _ := json.Marshal(identity)
return fmt.Sprintf("%x", sha256.Sum256(data))
}
// DeferredSyncAssets 仅读取逻辑清单,不发起下载。
func DeferredSyncAssets() ([]*entity.File, error) {
return deferredSyncAssets()
}
func deferredSyncAssets() ([]*entity.File, error) {
exists, err := assetDownloadStateExists()
if err != nil || !exists {
return nil, err
}
if Conf.Repo == nil || len(Conf.Repo.Key) == 0 {
return nil, errors.New(Conf.Language(377))
}
return dejavu.ReadDeferredAssets(assetDownloadStatePath(), Conf.Repo.Key)
}
// 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()View on GitHub (pinned to 9f775e8a12)