> ## Documentation Index
> Fetch the complete documentation index at: https://xanots.docs.xano.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Troubleshooting

> What the CLI's refusals and exit codes mean, and what to do about each one — from a failed release to a frozen lock to a build that will not deploy.

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.

<Tip>
  Set `XANOTS_DEBUG=1` to append the untouched server response underneath any error. Nothing is
  ever discarded — only folded away for readability.
</Tip>

## 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**.

| Code  | Meaning                                                | What to do                                                                        |
| ----- | ------------------------------------------------------ | --------------------------------------------------------------------------------- |
| `0`   | Success                                                | —                                                                                 |
| `1`   | General failure                                        | Read the message; it names what it could not do.                                  |
| `2`   | Validation failed (`preflight`, codegen verify)        | Your bundle did not survive the round trip. Re-run with `--verbose` for the diff. |
| `3`   | **Static** deploy failed, after the backend deployed   | The backend is live. Re-run with `--static` to retry just the frontend.           |
| `4`   | A microservice was not ready                           | The deploy happened; the microservice had not come up in time.                    |
| `5`   | **Tests ran and failed**                               | A real test failure — read the suite output.                                      |
| `6`   | Tests could not be reached                             | The suite never ran. Usually the environment is not up yet, not a test problem.   |
| `7`   | A newer `@xanots/sdk` is available (`upgrade --check`) | Informational.                                                                    |
| `130` | Interrupted (Ctrl-C)                                   | —                                                                                 |

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](/guides/workflow-repo#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](/guides/development-workflows#what-a-xano-branch-actually-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](/guides/workflow-repo), 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:

```bash theme={null}
xanots workspace export --path live.json
xanots lock import live.json --entry=xano/index.ts --yes
```

### 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:

```bash theme={null}
xanots lock rename --entry=xano/index.ts function signup register
```

Commit the resulting `xano.lock` in the same PR. See [Renames](/guides/git-and-merges#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](/guides/git-and-merges#resolving-a-xano-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:

```bash theme={null}
xanots login --paste
```

`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](/guides/workflow-repo#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:

```bash theme={null}
xanots workspace details
```

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
(<kbd>Cmd/Ctrl</kbd>+<kbd>Shift</kbd>+<kbd>R</kbd>), or bust it from a script:

```bash theme={null}
curl -s "$URL/?nocache=$(date +%s)" | grep XANO_HOST
```

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:

```ts theme={null}
import { fileUrl } from "@xanots/sdk";
<img src={fileUrl(row.avatar, HOST) ?? ""} />
```

### "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

```bash theme={null}
xanots status              # who am I, which workspace, which environment
xanots workspace details   # instance, id, name, guid
xanots whoami              # the account's instance origin
xanots version             # the installed @xanots/sdk
```

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