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: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 calledxanots 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:
--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:
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 stays0 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
XANOTS_DEBUG=1 for the raw response.