Skip to main content
Most of what the CLI prints when it stops is a refusal, not a crash — it checked something, did not like the answer, and declined rather than doing damage quietly. This page maps the ones you are most likely to meet to their cause and their fix.
Set XANOTS_DEBUG=1 to append the untouched server response underneath any error. Nothing is ever discarded — only folded away for readability.

Exit codes

Useful in CI, where the code is often all you get. A non-zero code from a command that also printed a URL usually means the main action succeeded and a follow-up step did not. Codes 3, 4 and 6 share a shape worth internalising: the deploy itself committed. Do not re-run the whole thing assuming nothing happened.

Releases that refuse

”…would drop column …”

A column your schema no longer defines. The release names it and asks before doing it, on an ordinary release with no destructive flag. Answer no unless you are certain. Removing a column destroys every value in it, and no rollback brings the data back — see when a release goes wrong. If the drop is intentional, take a backup first.

A prune is refused, or asks about an object you do not recognize

--prune only deletes objects this project released, and xano.lock is what defines that scope. A planned deletion with no lock entry is something your project never created — a table built in the UI, another team’s API group — so the release refuses rather than deleting it. A prune with no lock at all is refused outright: without one, every deletion would be a guess. To delete something genuinely yours, import its identities first with xanots lock import.

”—branch … cannot stage N changes to this workspace’s SHARED schema”

Branches scope logic, not tables — see what a branch isolates. Your three answers: take the schema change out of this release, drop --branch because applying it is what you wanted, or pass --allow-shared-schema-changes knowingly. A release also refuses when the live workspace could not be read — a failed read is not evidence that there is no schema change.

A --branch release refuses, or workspace branch is not in xanots help

Expected for now: branch releases are still rolling out instance-side. The flags parse and run, but they are not yet advertised in help or shell completion, and a release refuses outright unless the server confirms it planned against the branch you named — failing closed rather than overwriting your live branch. Nothing is wrong with your setup. Use Repo is the truth, which needs none of these commands.

Every object is a “create” when you expected updates

A merge matches objects by the identity your project assigns them, so it only recognizes a workspace it has released to before. Releasing into one built by hand — or populated by --replace, which mints its own identities — matches nothing. Fix it before releasing by importing the live identities:

The release says no changes and you expected changes

That is the comparison working: the workspace already matches your code. Check you edited what you think you did (git diff), and that you are pointed at the workspace you think you are (xanots workspace details).

Lock problems

”lock entry … matches no exported object”

You renamed something in code. Move its lock entry so the rename stays a rename instead of a delete-plus-create:
Commit the resulting xano.lock in the same PR. See Renames.

--frozen-lock fails the CI build

The export would have changed xano.lock, which almost always means someone did not commit it. Run xanots export ./xano/index.ts locally and commit the result — do not remove the flag, since catching this is its entire job.

A merge conflict in xano.lock

Normal, and usually benign — two branches each added entries. Take both sides and let the export rewrite the file. Full walkthrough: resolving a lock conflict.

Auth and environment

login hangs, or the browser cannot reach this machine

On a remote shell, container, or Codespace the 127.0.0.1 redirect lands nowhere. Use:
XANO_NO_BROWSER is not the same thing — it only suppresses the browser launch and still needs the redirect to arrive here.

A pipeline blocks forever

Something called xanots login, which waits on browser consent. CI uses the three environment variables instead — see automating it.

”set all three variables together”

XANO_INSTANCE_URL, XANO_WORKSPACE_ID and XANO_META_TOKEN are all-or-nothing by design. Setting some is a hard error rather than a quiet fallback, so a workflow with one misspelled secret cannot deploy against whatever credential happens to be on the runner.

Commands act on the wrong workspace

One credential addresses exactly one instance and one workspace — there is no --workspace flag. Ask which:
Note the resolution order: an explicit --config/$XANO_CONFIG wins, then project-local ./.xano/auth.json, then the shared ~/.xanots/auth.json. The three environment variables outrank all of them, and whichever they displace is named on stderr.

Deploy problems

window.XANO_HOST looks missing in the browser

Almost always caching. The static host serves index.html with Cache-Control: max-age=3600, so a browser can hold a pre-injection copy for up to an hour. Hard-reload (Cmd/Ctrl+Shift+R), or bust it from a script:
Grep for the bare token XANO_HOST — the injected line uses bracket notation (window["XANO_HOST"]=…), so searching for the literal window.XANO_HOST finds nothing even when it is there.

A stored file 404s, or an <img> is broken

Do not use the url field a file column returns — on a tenant-scoped environment it addresses the instance host without the /tenant/<name> segment. Build it from path instead:

“Frontend is live” never appears

A warning, not a failure. The upload succeeded; the edge had not confirmed it was serving this build within the poll window. The exit code stays 0 and the summary records "verified": false. Pass --skip-liveness if the URL is not reachable from the machine running the CLI.

Ephemerals are not available on this instance

Not every instance has them enabled; deploy says so and names who can turn them on. There is no second destination to fall back to, but xanots export and xanots preflight still work.

Still stuck

Then re-run the failing command with XANOTS_DEBUG=1 for the raw response.