siyuan-note/siyuan · warning

Data sync is in progress, please wait until data sync is…

Error message

Data sync is in progress, please wait until data sync is completed and try again

What it means

MoveLocalShorthands moves locally stored shorthand files into a notebook, but it must not run concurrently with data sync because both mutate data files. It tries syncLock.TryLock() and, if a sync is holding the lock, returns the i18n message 222 asking to wait until data sync completes.

Solutions

  1. Retry MoveLocalShorthands after the sync completes (listen for sync-finished push events)
  2. Schedule shorthand movement for idle periods when no sync is in progress
  3. Check sync status via the sync API before invoking the move

Example fix

// before
_, err := model.MoveLocalShorthands(boxID) // may fail during sync
// after
for {
    retIDs, err := model.MoveLocalShorthands(boxID)
    if err == nil || !strings.Contains(err.Error(), Conf.Language(222)) {
        break
    }
    time.Sleep(time.Second) // wait for sync to finish, then retry
}
Defensive patterns

Strategy: retry

Validate before calling

const status = await api.getSyncState()
if (status.syncing) { await waitForSyncCompletion(); }

Try / catch

try { await api.moveLocalShorthands(boxID) } catch (e) { if (String(e).includes('sync is in progress')) { setTimeout(retryMove, 5000); } else throw e }

Prevention

When it happens

Trigger: Calling MoveLocalShorthands (directly or via the shorthand consumption flow) while model sync operations hold syncLock — e.g. an automatic cloud sync running in the background at the same moment shorthands are processed.

Common situations: Startup or timer-driven shorthand consumption racing an auto-sync; user-triggered sync overlapping shorthand import; long syncs on slow networks making the race more likely.

Related errors


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

Appendix: source

Thrown at kernel/model/shortcuts.go:47

	"sync"
	"time"

	"github.com/88250/gulu"
	"github.com/88250/lute/ast"
	"github.com/88250/lute/parse"
	"github.com/siyuan-note/logging"
	"github.com/siyuan-note/siyuan/kernel/cache"
	"github.com/siyuan-note/siyuan/kernel/treenode"
	"github.com/siyuan-note/siyuan/kernel/util"
)

func MoveLocalShorthands(boxID string) (retIDs []string, err error) {
	shorthandsDir := filepath.Join(util.ShortcutsPath, "shorthands")
	if !gulu.File.IsDir(shorthandsDir) {
		return
	}
	if !syncLock.TryLock() {
		err = errors.New(Conf.Language(222))
		return
	}
	defer syncLock.Unlock()

	entries, err := os.ReadDir(shorthandsDir)
	if nil != err {
		logging.LogErrorf("read dir [%s] failed: %s", shorthandsDir, err)
		return
	}
	if !IsShorthandSaveBoxAvailable(boxID) {
		err = errors.New(Conf.Language(375))
		return
	}

	assetsDir := filepath.Join(util.DataDir, "assets")
	for _, entry := range entries {
		if entry.IsDir() && "assets" == entry.Name() {
			assetsEntries, readErr := os.ReadDir(filepath.Join(shorthandsDir, entry.Name()))

View on GitHub (pinned to 9f775e8a12)