Skip to main content
There is no rollback command. Production always runs a release, so going back means serving the previous one again, with the commands below. Each of them restores logic. None of them restores a table change or the rows it destroyed.

On your workspace: switch live back

A promote lands on a new Xano branch and leaves the previous one in place, so going back is switching live to it. Every switch prints the exact command that undoes it, whether it came from promote --set-live or workspace branch set-live:
Under --json the same label is previousLive. If you no longer have the output, list the Xano branches; the one you promoted before is still there:
--expect-live v1.4.0 refuses unless v1.4.0 is live, checked before asking and again immediately before switching, so a rollback never undoes someone else’s newer release by accident. A check that fails exits 2 with SDK_LIVE_BRANCH_MISMATCH. Off a terminal, add --yes. Keep the previous release’s Xano branch until the new one has served for a while. Once you delete it with workspace branch delete, the way back is promoting the previous release again.

On a tenant: deploy the previous release

A tenant serves exactly one release, so going back is deploying the release it ran before:
It is a replace like any other tenant deploy. A table the newer release added is dropped with its rows, a column it added loses its values, and values a conversion rewrote are not converted back. The confirmation names each of these before you answer; read it.

After a merge: the backup Xano branch

A merge into the live Xano branch (deploy --to workspace) leaves no release to go back to. Take a snapshot first with --backup-branch, and the way back is switching live to it:
With no label, --backup-branch derives one and prints it. The snapshot holds the live Xano branch’s logic only; a column the merge dropped stays dropped after the switch back.

Table changes are never rolled back

Tables are shared by every Xano branch, so a table change reaches live when a release lands and stays when you switch live back. On a tenant, deploying the previous release changes the tables again rather than restoring them. In both cases a dropped column or table comes back empty, if it comes back at all.
  • Change a column across two releases (expand, backfill, contract), so every release can be rolled back to the one before it. See Schema changes.
  • Back up the workspace or tenant in the Xano dashboard before a release that drops or rewrites a column. A backup is how you recover the rows.
  • Preview with deploy --to … --dry-run and read droppedColumns before you ship.

Roll back the frontend

A frontend is published separately from the backend, and neither a promote nor a rollback touches the static host. After you switch live back, publish the build that belongs to the previous release, built from its git tag:
--release checks that the release exists and reports it with the publish. --branch refuses unless v1.3.2 is the live Xano branch, so the frontend cannot land in front of a backend it was not built for. On a tenant, publish the same build with --to tenant:prod.

Recover a tenant deploy that stopped partway

A tenant deploy can stop partway when the tenant’s rows break something the release adds: a unique index over rows that share a value, a required field that rows leave empty, or a stored value a retype cannot convert. The tenant may then serve part of each release. The run fails with completed: "no", partlyReplaced: true, the constraint it hit, and recoverWith, the tenant deploy of the release the tenant ran before. Run it:
That puts the previous release’s logic and definitions back. Values a conversion already rewrote stay rewritten. Fix the rows the constraint names, then deploy the new release again.

Recover a release write whose outcome is unknown (exit 9)

Exit 9 means a release create, promote, tenant deploy or release transfer sent its write and lost the answer: a timeout, a dropped connection, a server error, or Ctrl-C mid-write. The write may have happened. Read before you retry, never retry blind. The run’s document (--json, or stdout whenever it is not a terminal) carries what to read: What to check for each command:
  • release create. Run xanosdk release list and look for the name, or the name with a dash and four hex characters (v1.4.0-a019). The platform stores a write under a taken name with that suffix instead of refusing it, so a blind retry can leave two releases. If the cut is stored under a suffixed name, delete the stray copy with xanosdk release delete and keep one.
  • promote. Run xanosdk workspace branch list --json. If the label is there, the release landed. If it is absent after resolveNotBefore, nothing landed: re-run with the same --branch and --yes. A bare re-run lands a second Xano branch.
  • tenant deploy. Run xanosdk tenant get prod --json and compare deployedAt with its value before the run. A deployedAt that moved means the release landed. One that did not move can also mean a deploy that stopped partway, so deploy the previous release again to be sure.
  • release transfer. Run the same transfer with --dry-run. It reports whether the copy is at the destination.
Exit codes and outcomes lists every code.

Next

CI/CD: run the release flow, and these checks, from your pipeline.