siyuan-note/siyuan · error
can not get or create rollback box
Error message
can not get or create rollback box
What it means
getRollbackBox resolves the notebook to roll back into: it returns Conf.Box(boxID) if mounted, otherwise falls back to a notebook named "Rollback" (creating it if needed). If neither the target box nor a Rollback box can be resolved or created, the kernel throws this error to abort the rollback operation instead of writing history data to an undetermined notebook.
Source
Thrown at kernel/model/history.go:1448
if nil == ret {
boxName := "Rollback"
ret = GetBoxByName(boxName)
if nil == ret {
var id string
id, err = CreateBox(boxName)
if nil != err {
return
}
_, err = Mount(id)
if nil != err {
return
}
ret = Conf.Box(id)
created = true
}
}
if nil == ret {
err = errors.New("can not get or create rollback box")
return
}
return
}
View on GitHub (pinned to 8641553a1f)
Solutions
- Mount (or re-open) the original notebook in the current workspace so Conf.Box(id) succeeds before rolling back
- Ensure a notebook named "Rollback" exists or can be created; if none exists, create an unencrypted notebook named exactly "Rollback"
- Verify the boxID passed to the rollback API matches an existing notebook ID in conf.json
- Check kernel logs for the preceding workspace/configuration errors and restart the kernel so the notebook list is reloaded
Example fix
// before: rolling back history of an unmounted box
rollbackDocHistory("20240101120000-abcdefg", "/history/...", "unmounted-box-id")
// after: ensure the box is open first (kernel side)
if nil == Conf.Box(boxID) {
OpenBox(boxID) // mount the notebook before invoking rollback
}
box, _, err := getRollbackBox(boxID) Defensive patterns
Strategy: validation
Validate before calling
// caller-side check before rollback
box := conf.GetBox(boxID)
if box == nil {
box = model.GetBoxByName("Rollback")
}
if box == nil {
return fmt.Errorf("rollback target notebook %q unavailable; mount it or create a \"Rollback\" notebook", boxID)
} Type guard
func rollbackTargetReady(boxID string) bool {
return conf.GetBox(boxID) != nil || model.GetBoxByName("Rollback") != nil
} Prevention
- Do not remove notebooks referenced by pending rollback operations
- Keep a notebook named "Rollback" in workspaces where you use history rollback
- Always call rollback APIs with box IDs taken from Conf.Box listing, not from user input
- After switching workspaces, re-verify notebook IDs before issuing rollback calls
When it happens
Trigger: Calling RollbackDocHistory or RollbackRepoSnapshotFile when the original notebook is not in the current configuration AND no notebook named "Rollback" exists and the implicit fallback creation fails (e.g. invalid/empty box id, workspace configuration not loaded, box creation path rejected).
Common situations: Rolling back history after the source notebook was removed from the workspace or the workspace was switched; corrupted conf.json losing the notebook entry; running the API against a different workspace than the one holding the notebook; tests calling the rollback API with a fabricated box id.
Understand the failure class
Background: "Not found" and "does not exist" errors: why "Task not found", "No such folder", and "Can't find" fire when a lookup comes back empty — this error's family across 14 libraries.
Related errors
- Conf.Language(371)
- Conf.Language(314)
- install local marketplace package failed: %w; rollback faile
- Please unlock the encrypted notebook first
- %w; cleanup failed: %v
AI-assisted analysis of siyuan-note/siyuan@8641553a1f (2026-09-11).
Data as JSON: /api/errors/2aeb926d410fd754.
Report an issue: GitHub.