Exit Codes
The CLI reports results through structured exit codes. Scripts branch on them, and CI decides from them whether to abort the pipeline.
Exit Code Reference
| Exit code | Constant | Meaning | Typical trigger |
|---|---|---|---|
0 | SUCCESS | Success | The command completed normally |
1 | ERROR | Generic error (fallback) | No semantic category matched |
2 | AUTH_FAILED | Authentication failure | Not logged in, token expired, no permission |
3 | INVALID_INPUT | Parameter or input validation failure | Missing required value, invalid enum, bad format, missing envId in non-interactive runs, command not available for the environment mode |
4 | NOT_FOUND | Resource not found | Invalid function name or environment ID, missing collection, missing file or object |
5 | API_ERROR | Cloud API or network error | CloudBase API error, request timeout, rate limiting, SDK exception |
6 | FILE_ERROR | Local file or config error | cloudbaserc.json missing or corrupt, path does not exist, read/write failure, dependencies not installed |
How the Code Is Resolved
The exit code lives on the error object and is resolved in the following order, stopping at the first match:
| Step | Basis | Example |
|---|---|---|
| 1 | exitCode carried by the error | Exit semantics set explicitly where the error is raised |
| 2 | Exact match on a CLI-local error code | TOKEN_EXPIRED → 2, FUNCTION_NOT_FOUND → 4, INVALID_CONFIG → 6 |
| 3 | Base segment of a cloud API error code | FailedOperation.PGExecuteSqlError → FailedOperation → 5 |
| 4 | Prefix of a manager-node custom code | PREFLIGHT_* → 6, CLOUD_* → 5, BUILD_* → 3 |
| 5 | Fallback | 1 |
To predict the exit code of a given error, look at error.code in the --json output: local codes match the table, cloud API codes use the segment before the first ., manager-node codes use their prefix.
Branching in Scripts
tcb fn deploy app -e my-env-id
case $? in
0) echo "Deployed" ;;
2) echo "Authentication failed"; tcb login ;;
5) echo "Cloud API error, retrying in 5s"; sleep 5; tcb fn deploy app -e my-env-id ;;
*) echo "Failed with exit code $?"; exit 1 ;;
esac
5 is the only code worth retrying automatically; retrying anything else just wastes time:
for i in 1 2 3; do
tcb fn deploy app -e my-env-id && exit 0
[ $? -eq 5 ] || exit $?
sleep 5
done
exit 1
In CI
CI treats any non-zero exit code as a failure and aborts the step, so no extra handling is usually needed. To branch on specific codes, read $? in the shell:
- name: Deploy function
env:
ENV_ID: ${{ secrets.ENV_ID }}
run: |
tcb fn deploy app --env-id "$ENV_ID" --json --yes
code=$?
if [ $code -eq 5 ]; then
sleep 5
tcb fn deploy app --env-id "$ENV_ID" --json --yes
exit $?
fi
exit $code
steps.<id>.outcome only reports success / failure; it does not expose the actual exit code.
JSON Error Object
With --json, a failure is written to stdout:
{
"error": {
"code": "FUNCTION_NOT_FOUND",
"message": "Function app does not exist",
"exit_code": 4,
"solution": "Check the function name, or run tcb fn list to see existing functions",
"docs": "https://docs.cloudbase.net/cli-v1/functions/list",
"requestId": "1a2b3c4d-0000-0000-0000-000000000000"
}
}
code: the error code, which decides the exit codeexit_code: the process exit code, identical to$?solution/docs/requestId: present only when the error carries them
Notes
- Exit codes are not HTTP status codes:
4means resource not found, not 404;5means cloud API error, not 500 --yesonly skips confirmation prompts; it does not change the result or the exit code- Chain commands with
&&orset -eso a failing command stops the rest - Add
--verboseto print stack traces and API request parameters when you need to locate the failure