Skip to main content
Every xanosdk command ends with an exit code, and off a terminal it also writes one JSON document to stdout. The exit code says that something failed; the document says which thing. In a script or CI job, branch on the exit code first and on error.code second. Never match on the message text: messages are reworded between releases, codes are not.

Exit codes

A failure document’s error.exitCode always matches the process exit code. Codes 3, 4, 5 and 6 share a shape: the deploy itself happened. Do not re-run the whole deploy as if nothing landed. A signal that arrives while a write is on the wire ends the run with 9, not 130, 143 or 129, because what you need to know next is “read before you retry”.

JSON output

stdout carries one JSON document whenever it is not a terminal, or whenever you pass --json. Progress and messages go to stderr, so a pipe or a CI log step reads clean JSON:
Three things keep text even when piped: --help, xanosdk version (so $(npx xanosdk version) works), and a command whose stdout is its data, such as export to stdout or --path -. Those write a failure document only under --json, because appending one to the data would corrupt it. Every date in a --json document is ISO 8601 UTC, for example 2026-10-01T09:13:16.000Z.

The failure document

A command that fails under --json, or with stdout piped, writes this instead of its normal document, so stdout is never empty:
SDK_ERROR is the code for any failure that has no code of its own yet. For those, exitCode tells the kinds apart: 8 for a named thing that is missing or a network failure before any write, 1 for the rest. Set XANOSDK_DEBUG=1 to append the untouched server response to any failure message.

Operation outcome

The four release writes, release create, promote, tenant deploy and release transfer, answer one question in one shape: does the outcome you asked for exist?
Each entry in steps has its own completed: yes, no, unknown, or skipped for a step an earlier failure kept from running. For promote, the verify step only checks the landing: a verification that could not run leaves the landing yes.

Settling an unknown

unknown is settled by a read, never by a retry:
  1. Run the resolveWith command. It is read-only.
  2. Follow resolveSteps, which says what to do with each answer the read can give.
  3. Treat “absent” as proof only after resolveNotBefore. Before then the server may still be finishing the write.
A blind retry is the one wrong move. The platform stores a release under a taken name with a dash and four hex characters added (v1.4.0-a019) and reports success, so a second release create after a lost answer can leave two releases. A second promote lands a second Xano branch.

Interrupted and declined runs

A run ended by a signal writes interrupted: true. With a write on the wire the outcome is unknown (exit 9); with none it is cancelled (exit 130, 143 or 129). Either way landed says what the run had already landed. A declined confirmation exits 0 and still writes its document: the operation commands write the step as no, and the delete commands (tenant delete, ephemeral delete, release delete, workspace branch delete) write deleted: false, declined: true.

Next