For Divvent’s own team. It is generated from the operations document in our repository, which is the one to edit. If you use Divvent, the help centre is for you.
3. Rolling back
divvent deploy <modelDir> --rollback --tenant <tenant>
Puts the Worker back to the version this environment was serving before the last deploy. The environment comes from the state the deploy recorded, not from a flag: a rollback undoes a deploy that happened, and which environment that was is a fact rather than a choice.
Code only. To bring the data back as well:
divvent deploy <modelDir> --rollback --restore --tenant <tenant>
--restore puts the database back to the Time Travel bookmark the deploy took before it migrated. Thirty days, which is the whole of the rollback window — D1's retention, not a setting. Anything longer is the nightly dump.
A trial rolls back as a trial: pass the same --instance its deploy had (<application>--<trial>). The deploy records the instance it composed, and the rollback takes the target from that record and refuses a different one, so a trial's rollback cannot reach production's Worker or production's database. It used to derive the names from the tenant alone, which composed production's.
Things it will refuse, before anything moves, and each is correct:
- "no snapshot was taken for this deploy" — the migration was additive, so there is nothing to restore and the code rollback alone is enough. (This used to put the code back first and then refuse; now it changes nothing.)
- "has no previous version recorded" — this deploy was the environment's first. Delete the Worker if you want it gone; there is nothing to go back to.
- **"was bound to
<database>… not this target's"** — the record names a database this target does not own: another target's record, or a deploy that bound one with--reuse-database. Restoring it would rewind whatever else uses it.
A restore happens at most once per deploy. Running the rollback again resumes it — the Worker is pointed at the same version — and does not restore a second time, which would discard the writes made in between.
3.1 Through the queue: a customer's rollback
A rollback the portal asks for is a platform_deploy_request of kind rollback, and divvent deploys performs it by running exactly the command above, on the target the request names:
divvent deploy <materialised revision> --env prod --tenant <slug> [--instance <slug>--<trial>] --via <env> --rollback [--restore] --json
- **
--restoreonly when the request says so** (restore, recorded with the request by whoever asked) and the deploy took a bookmark. A restore discards every write since the bookmark, so it is never the runner's decision. A customer's rollback asks (Ant, 2026-09-23): the portal's Roll back is code only unless the "also put the data back" box is ticked, which is offered only where the undone deploy took a bookmark and states its age.customer.rollbackrefusesrestorewith no bookmark to go back to. - Production or one trial.
customer.rollbacktakestrial, and each trial's card on the Releases screen has its own Roll back — an editor's too, clicked, because a trial is never production; production's stays an owner's or an admin's, typed. The data question is asked about that target's own bookmark. - It undoes the deploy that is running, and only that. The target's record must be of the revision it runs, and must say it replaced the revision the request goes back to; otherwise it refuses and changes nothing. A rollback that already happened resumes. So a target whose last finished request was a rollback is offered no second one (
rollbackTargetanswers nothing,rolledBacksays which rollback it is sitting on): the rollback's owndisplacedis the revision it undid, and the runner would refuse it. A deploy to the target moves it forwards and makes it roll-backable again. - The outcome says what happened: the Worker version put back, and either
database <name> (<id>) restored to bookmark <bookmark>or why the data was not restored — with the bookmark it did not use, which is still there within D1's thirty days. The same sentence is on thedeploy.doneaudit row, anddeploy.rolled-backrecords the database and the bookmark again. - It compiles the revision only to learn the names and builds nothing, so it works on a fresh runner.
- It is exercised against staging every week, both ways, by the acceptance round's step 6 (§6c): a rollback with the box ticked, then one without, each pressed on the Releases screen and each outcome read back for the Worker version and the database sentence above.
---