- Overview
- Get started
- Concepts
- Using UiPath CLI
- How-to guides
- CI/CD recipes
- Command reference
- Overview
- Exit codes
- Global options
- uip codedagent
- uip coder
- uip context-grounding
- uip docsai
- uip function
- uip guardrails
- uip llm-configuration
- uip llm-gateway
- uip model-hub
- add-test-data-entity
- add-test-data-queue
- add-test-data-variation
- analyze
- build
- create-project
- diff
- find-activities
- get-analyzer-rules
- get-default-activity-xaml
- get-errors
- get-manual-test-cases
- get-manual-test-steps
- get-library-object-repository
- get-object-repository
- get-versions
- get-workflow-example
- indicate-application
- indicate-element
- inspect-package
- install-data-fabric-entities
- install-or-update-packages
- list-data-fabric-entities
- list-instances
- list-workflow-examples
- pack
- publish
- remote
- restore
- run, debug & execution
- run-file
- search-templates
- start-studio
- stop-execution
- tm
- uia
- uip tasks
- uip traces
- uip traces feedback
- Migration
- Reference & support
Exit code contract for UiPath CLI, covering five tiers (0 through 4) and code 130 for user cancellation, with scripting guidance.
Every uip invocation ends with a numeric exit code. Scripts and CI pipelines branch on these codes to distinguish success, a transient error worth retrying, a credential problem that needs human attention, and a misuse of the command line.
Contract
The exit code is determined by the Result field in the command's output envelope. The host maps each Result value to a single exit code:
| Exit code | Result value(s) | Meaning |
|---|---|---|
| 0 | Success | The command completed and its intent was achieved. |
| 1 | Failure, ConfigError | Generic failure or a configuration problem the CLI can detect before reaching the server (missing tenant, missing file on disk, etc.). |
| 2 | AuthenticationError | The session is not authenticated, the token is expired, or Orchestrator rejected the credentials (401 / 403). |
| 3 | ValidationError | The command was invoked with invalid input — unknown flag, flag with wrong value, mutually-exclusive flags, malformed --output-filter, and so on. |
| 4 | TimeoutError | A long-running operation exceeded its deadline. Emitted by uip tm perf-scenario execute --wait when its --timeout-sec elapses; the envelope itself reads Result: "Failure". |
Additionally:
| Exit code | Source | Meaning |
|---|---|---|
| 130 | Shell convention (128 + SIGINT) | The user cancelled an interactive prompt (Ctrl+C during uip login, uip skills install, uip completion, etc.). |
No other exit codes are emitted by UiPath CLI. A value outside this table indicates an abnormal termination — uncaught crash, runaway child process, or the shell reporting a signal — and should be investigated, not pattern-matched.
Stability
0,1,2,3are stable within a MAJOR release. A command that exits with3(validation) for a given input will keep exiting with3across MINOR and PATCH bumps.4means timeout. Onlyuip tm perf-scenario execute --waitemits it today; other long-running commands may start doing so in a MINOR release, so scripts should already handle4as "timeout".- New codes may be added in a MAJOR release, with prior notice in the release notes. The current set covers every failure mode UiPath CLI 1.x needs.
See Versioning and stability for the broader semver contract.
Reading the exit code in scripts
bash / sh / zsh
uip or folders list
case $? in
0) echo "ok" ;;
1) echo "command failed" ;;
2) echo "not authenticated — run uip login" ;;
3) echo "bad input — check flags" ;;
4) echo "timed out" ;;
130) echo "cancelled by user" ;;
*) echo "unexpected exit: $?" ;;
esac
uip or folders list
case $? in
0) echo "ok" ;;
1) echo "command failed" ;;
2) echo "not authenticated — run uip login" ;;
3) echo "bad input — check flags" ;;
4) echo "timed out" ;;
130) echo "cancelled by user" ;;
*) echo "unexpected exit: $?" ;;
esac
set -e (or set -o errexit) aborts the script on any non-zero exit. This is the common default for CI; combine it with trap or with per-command handling when you need to distinguish between codes:
set -euo pipefail
if ! uip or folders list --output json > folders.json; then
case $? in
2) uip login ; uip or folders list --output json > folders.json ;;
*) exit $? ;;
esac
fi
set -euo pipefail
if ! uip or folders list --output json > folders.json; then
case $? in
2) uip login ; uip or folders list --output json > folders.json ;;
*) exit $? ;;
esac
fi
PowerShell
uip or folders list
switch ($LASTEXITCODE) {
0 { Write-Host "ok" }
1 { Write-Host "command failed" }
2 { Write-Host "not authenticated" }
3 { Write-Host "bad input" }
4 { Write-Host "timed out" }
130 { Write-Host "cancelled" }
default { Write-Host "unexpected exit: $LASTEXITCODE" }
}
uip or folders list
switch ($LASTEXITCODE) {
0 { Write-Host "ok" }
1 { Write-Host "command failed" }
2 { Write-Host "not authenticated" }
3 { Write-Host "bad input" }
4 { Write-Host "timed out" }
130 { Write-Host "cancelled" }
default { Write-Host "unexpected exit: $LASTEXITCODE" }
}
GitHub Actions
Any non-zero exit in a run: step fails the job by default. To branch on specific codes, capture the code explicitly:
- name: Query Orchestrator
id: folders
run: |
uip or folders list --output json > folders.json
echo "exit_code=$?" >> "$GITHUB_OUTPUT"
continue-on-error: true
- name: Re-authenticate if expired
if: steps.folders.outputs.exit_code == '2'
run: uip login --client-id env.UIPATH_CLIENT_ID --client-secret env.UIPATH_CLIENT_SECRET --tenant "$TENANT"
env:
UIPATH_CLIENT_ID: ${{ secrets.UIPATH_CLIENT_ID }}
UIPATH_CLIENT_SECRET: ${{ secrets.UIPATH_CLIENT_SECRET }}
TENANT: ${{ vars.UIPATH_TENANT }}
- name: Query Orchestrator
id: folders
run: |
uip or folders list --output json > folders.json
echo "exit_code=$?" >> "$GITHUB_OUTPUT"
continue-on-error: true
- name: Re-authenticate if expired
if: steps.folders.outputs.exit_code == '2'
run: uip login --client-id env.UIPATH_CLIENT_ID --client-secret env.UIPATH_CLIENT_SECRET --tenant "$TENANT"
env:
UIPATH_CLIENT_ID: ${{ secrets.UIPATH_CLIENT_ID }}
UIPATH_CLIENT_SECRET: ${{ secrets.UIPATH_CLIENT_SECRET }}
TENANT: ${{ vars.UIPATH_TENANT }}
Matching exit codes to the JSON envelope
When --output json is in effect (the default), the envelope carries the same information as the exit code, plus a human-readable message:
{
"Result": "ValidationError",
"Message": "Unknown option '--folder-pth'. Did you mean '--folder-path'?",
"Instructions": "Run 'uip or folders list --help' to see valid options."
}
{
"Result": "ValidationError",
"Message": "Unknown option '--folder-pth'. Did you mean '--folder-path'?",
"Instructions": "Run 'uip or folders list --help' to see valid options."
}
A pipeline can branch on $? for fast decisions (retry on 2, abort on 3) and parse the envelope for the full error picture (surface the Message in a Slack webhook, ticket the Instructions alongside the failing step, etc.).
Every failure envelope also carries ErrorCode and Retry — see Output formats — the envelope. They're a finer-grained signal than the exit code alone: several distinct ErrorCode values (for example not_found and rate_limited) can map to the same exit code 1, but only one of them is worth retrying. See Scripting patterns — branching on ErrorCode and Retry.
Command-specific semantics
Exit codes are status codes, not success codes. A command that reports Success with a Data payload indicating "no results found" still exits 0. For example, uip or folders list --all --name DoesNotExist returns {"Data": [], …} and exits 0 — because the list query succeeded; the absence of matches is a valid outcome, not a failure.
Where a command needs to distinguish "the operation succeeded" from "the domain outcome is positive", it says so in its reference page:
uip tm testsets run— always exits0once Orchestrator accepts the test run request and returns theExecutionId. The pass/fail verdict comes from a separateuip tm wait+uip tm report getchain; branch onData.Failedin the report output.uip tm waitemits exit code2on timeout (a domain-specific reuse of the authentication-error slot — noted in uip tm wait and uip tm executions).uip tm perf-scenario execute --wait— exits4when--timeout-secelapses before the run finishes. The run itself keeps going; re-check it withperf-scenario results get.uip or jobs start --wait-for-completion— exits non-zero when the job reaches a terminalFaultedorStoppedstate. Without--wait-for-completion, the command exits0as soon as Orchestrator accepts the request, regardless of later job outcome.
Check the reference page for any command where the semantics of "success" are ambiguous.
See also
- Global options — the
--output,--output-filter,--log-level,--log-fileflags. - Scripting patterns — retries, polling, idempotent pipelines.
- Output formats — the envelope shape that mirrors the exit code.
- Versioning and stability — how the exit-code contract evolves across semver bumps.