siyuan-note/siyuan · warning
Related operations are being processed, please try again lat
Error message
Related operations are being processed, please try again later
What it means
Thrown by RollbackNotebookHistory when boxLock.LoadOrStore(boxID, true) returns loaded=true, indicating another operation is already holding the lock for this notebook ID. The boxLock is a sync.Map used to serialize concurrent notebook-level operations. The error message is Conf.Language(239) = "Related operations are being processed, please try again later". This is a transient concurrency guard, not a permanent failure.
Source
Thrown at kernel/model/history.go:610
encrypted, err := isEncryptedHistoryBoxDir(filepath.Join(util.HistoryDir, parts[0], boxID))
if err != nil {
logging.LogErrorf("inspect encrypted history path [%s] failed: %s", absPath, err)
return true
}
return encrypted
}
func RollbackNotebookHistory(historyPath string) (err error) {
historyPath, err = validateHistoryPath(historyPath)
if err != nil {
return
}
boxID, err := validateNotebookHistoryPath(historyPath)
if err != nil {
return
}
if _, loaded := boxLock.LoadOrStore(boxID, true); loaded {
return errors.New(Conf.Language(239))
}
defer boxLock.Delete(boxID)
from := historyPath
to := filepath.Join(util.DataDir, boxID)
if filelock.IsExist(to) {
return errors.New(Conf.Language(371))
}
if err = filelock.CopyNewtimes(from, to); err != nil {
logging.LogErrorf("copy file [%s] to [%s] failed: %s", from, to, err)
return
}
IncSync()
ReloadFiletree()
util.PushMsg(Conf.Language(372), 3000)
return nilView on GitHub (pinned to 251596fc0d)
Solutions
- Wait a moment and retry the rollback — the lock is released when the in-flight operation completes (typically within seconds).
- Disable the rollback button in the UI immediately after click and re-enable it on response to prevent duplicate submissions.
- As an API client, implement exponential backoff retry on this specific error (it is transient).
Example fix
// before
await post('/api/history/rollbackNotebookHistory', { historyPath })
// after — retry with backoff on the "operations being processed" error
async function rollbackWithRetry(historyPath, maxRetries = 3) {
for (let i = 0; i < maxRetries; i++) {
try {
return await post('/api/history/rollbackNotebookHistory', { historyPath })
} catch (e) {
if (e.code === 239 && i < maxRetries - 1) {
await sleep(500 * (i + 1))
continue
}
throw e
}
}
} Defensive patterns
Strategy: retry
Try / catch
// Retry with backoff on the concurrent-operation lock error
async function rollbackNotebookHistorySafe(historyPath, maxRetries = 3) {
for (let i = 0; i < maxRetries; i++) {
try {
return await post('/api/history/rollbackNotebookHistory', { historyPath })
} catch (e) {
if (e.code === 239 && i < maxRetries - 1) {
await sleep(500 * (i + 1))
continue
}
throw e
}
}
} Prevention
- Disable the rollback button immediately after click to prevent duplicate submissions.
- Implement client-side debounce on rollback triggers.
- Use exponential backoff retry for this transient concurrency error.
When it happens
Trigger: Calling POST /api/history/rollbackNotebookHistory while another rollback, file operation, or sync is already in progress for the same notebook ID. The lock is acquired per-notebook, so only same-notebook operations conflict. The lock is released (defer boxLock.Delete) when the first operation completes.
Common situations: User double-clicks the rollback button rapidly; two browser tabs initiate rollback on the same notebook simultaneously; a sync operation holds the lock while the user triggers rollback; an API client retries too aggressively.
Related errors
- Related operations are being processed, please try again lat
- encrypted notebook is locked, please unlock it first
- refresh OAuth credentials: %w
- The notebook already exists
- 239
AI-assisted analysis of siyuan-note/siyuan@251596fc0d (2026-08-12).
Data as JSON: /api/errors/a0224ab1a7cd025b.
Report an issue: GitHub.