- Overview
- Get started
- Concepts
- Using UiPath CLI
- How-to guides
- CI/CD recipes
- Command reference
- Overview
- Exit codes
- Global options
- uip codedagent
- uip docsai
- 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-versions
- get-workflow-example
- indicate-application
- indicate-element
- inspect-package
- install-data-fabric-entities
- install-or-update-packages
- list-data-fabric-entities
- list-workflow-examples
- pack
- restore
- run-file
- search-templates
- start-studio
- stop-execution
- uia
- uip traces
- Migration
- Reference & support
UiPath CLI user guide
This page collects the patterns that make uip easy to script against — in shell, PowerShell, and CI pipelines. Nothing here is specific to a single tool; every pattern builds on the contract that the exit code and JSON envelope expose consistently across commands.
Helpful defaults
Three design decisions make scripting straightforward:
- JSON is the default output. No
--output jsonneeded, whether you are in a terminal or a pipeline. - Stdout is JSON only; everything else is stderr. Logs, progress bars, and human-readable error text go to stderr, so capturing stdout gives you clean data.
- Exit codes are narrow and stable. Five values (
0,1,2,3,4) cover every documented failure mode, plus130for user cancellation. Scripts can branch without parsing strings.
Strict shell options
For bash / zsh, start scripts with:
#!/usr/bin/env bash
set -euo pipefail
#!/usr/bin/env bash
set -euo pipefail
-e— abort on any command that exits non-zero.-u— abort on an undefined variable.-o pipefail— propagate a failure from any stage of a pipeline, not just the last one.
For PowerShell:
$ErrorActionPreference = 'Stop'
$ErrorActionPreference = 'Stop'
Branching on exit codes
The Result value on the envelope maps one-to-one to the process exit code. Branch on the exit code for fast decisions; open the envelope for detail (see Exit codes for the full table).
if uip or folders list --output-filter "Data[?Name=='Shared'] | [0]" > shared.json; then
echo "Shared folder found"
else
case $? in
2) echo "re-authenticating"; uip login --client-id env.UIPATH_CLIENT_ID --client-secret env.UIPATH_CLIENT_SECRET --tenant "$UIPATH_TENANT" ;;
3) echo "bad flag — aborting"; exit 3 ;;
*) echo "unexpected failure"; exit 1 ;;
esac
fi
if uip or folders list --output-filter "Data[?Name=='Shared'] | [0]" > shared.json; then
echo "Shared folder found"
else
case $? in
2) echo "re-authenticating"; uip login --client-id env.UIPATH_CLIENT_ID --client-secret env.UIPATH_CLIENT_SECRET --tenant "$UIPATH_TENANT" ;;
3) echo "bad flag — aborting"; exit 3 ;;
*) echo "unexpected failure"; exit 1 ;;
esac
fi
Reading values out of the envelope
Use --output-filter (JMESPath) to extract values at the source, rather than piping through jq:
FOLDER_KEY=$(uip or folders list --all --name Shared --output-filter "Data[0].Key" --output plain)
FOLDER_KEY=$(uip or folders list --all --name Shared --output-filter "Data[0].Key" --output plain)
--output plain returns the bare value (no quotes) for a scalar filter result. For arrays and objects, --output json keeps the structure:
PROCESS_KEYS=$(uip or processes list --folder-path Shared --output-filter "Data[*].Key")
echo "$PROCESS_KEYS" | jq -r '.[]' | while read -r key; do
uip or jobs start "$key"
done
PROCESS_KEYS=$(uip or processes list --folder-path Shared --output-filter "Data[*].Key")
echo "$PROCESS_KEYS" | jq -r '.[]' | while read -r key; do
uip or jobs start "$key"
done
If you prefer jq end-to-end, capture raw JSON and chain:
FOLDER_KEY=$(uip or folders list --all --name Shared | jq -r '.Data[0].Key')
FOLDER_KEY=$(uip or folders list --all --name Shared | jq -r '.Data[0].Key')
Both approaches produce the same value. --output-filter is faster and validates at CLI-parse time; jq gives you the full JMESPath plus jq-specific constructs like [-1] (last element) and to_entries.
Re-authenticating on AuthenticationError (exit 2)
Access tokens expire. In a long-running script, the pattern is: run the command, fall back to uip login if the token is gone, retry once, then fail hard.
uip_retry() {
uip "$@" && return 0
local code=$?
if [[ $code -eq 2 ]]; then
uip login \
--client-id env.UIPATH_CLIENT_ID \
--client-secret env.UIPATH_CLIENT_SECRET \
--tenant "$UIPATH_TENANT" >/dev/null
uip "$@"
else
return $code
fi
}
uip_retry or folders list --all
uip_retry() {
uip "$@" && return 0
local code=$?
if [[ $code -eq 2 ]]; then
uip login \
--client-id env.UIPATH_CLIENT_ID \
--client-secret env.UIPATH_CLIENT_SECRET \
--tenant "$UIPATH_TENANT" >/dev/null
uip "$@"
else
return $code
fi
}
uip_retry or folders list --all
Keep retries bounded — a single auth retry handles token expiry; further retries would mask a misconfigured credential and burn rate limits.
Polling long-running operations
Some operations complete asynchronously on the Orchestrator side:
- Job execution — use
uip or jobs start --wait-for-completionto have the CLI poll for you. Default timeout is 300 seconds, adjustable with--timeout. Poll interval is 5 seconds, adjustable with--poll-interval. - Solution deployment —
uip solution deploy runpolls internally with a default timeout of 360 seconds. - Test execution —
uip tm testset executelaunches the run, returns anExecutionId, and exits immediately with0. To block until the run completes, chainuip tm wait(which polls and exits2on timeout). To read the pass/fail verdict after waiting, inspectData.Failedinuip tm report get. See uip tm testset, uip tm execution, and uip tm wait.
When the built-in polling is too coarse, or when the terminal state needs custom handling, poll yourself:
JOB_KEY=$(uip or jobs start "$PROCESS_KEY" --output-filter "Data.Jobs[0].Key" --output plain)
while :; do
STATE=$(uip or jobs get --job-key "$JOB_KEY" --output-filter "Data.State" --output plain)
case "$STATE" in
Successful) echo "done"; break ;;
Faulted|Stopped) echo "job $STATE"; exit 1 ;;
*) sleep 10 ;;
esac
done
JOB_KEY=$(uip or jobs start "$PROCESS_KEY" --output-filter "Data.Jobs[0].Key" --output plain)
while :; do
STATE=$(uip or jobs get --job-key "$JOB_KEY" --output-filter "Data.State" --output plain)
case "$STATE" in
Successful) echo "done"; break ;;
Faulted|Stopped) echo "job $STATE"; exit 1 ;;
*) sleep 10 ;;
esac
done
Always cap the loop on time — a Faulted job that ends up in a Pending loop will otherwise block forever:
DEADLINE=$(( SECONDS + 1800 ))
while (( SECONDS < DEADLINE )); do
# … as above …
done
[[ $SECONDS -ge $DEADLINE ]] && { echo "timed out"; exit 1; }
DEADLINE=$(( SECONDS + 1800 ))
while (( SECONDS < DEADLINE )); do
# … as above …
done
[[ $SECONDS -ge $DEADLINE ]] && { echo "timed out"; exit 1; }
Idempotent pipelines
Many uip commands are idempotent by design — re-running them with the same arguments either returns the existing resource or does nothing:
uip solution publish— re-publishing a package with the same name and version returns the existing version.uip tools install— a no-op if the tool is already installed.uip or processes create— will fail on duplicate name-in-folder; useuip or processes update-versionoruip or processes editin that case.uip resource assets deploy --from-file— upserts by key.
Combine these with set -e to build pipelines that are safe to re-run after a partial failure without cleanup steps.
Separating data from logs
Stdout is JSON. Stderr is everything else. Redirect them independently:
uip or folders list > folders.json 2> uip.log
uip or folders list > folders.json 2> uip.log
This is especially important in CI: a job that prints progress indicators or npm output inline with the data stream will produce mangled JSON for later steps to consume.
Handling empty results
A command that succeeds with zero rows in Data exits 0 — the list query worked, but nothing matched. Detect this with --output-filter:
COUNT=$(uip or folders list --all --name DoesNotExist --output-filter "length(Data)" --output plain)
if [[ "$COUNT" -eq 0 ]]; then
echo "no match"
exit 1
fi
COUNT=$(uip or folders list --all --name DoesNotExist --output-filter "length(Data)" --output plain)
if [[ "$COUNT" -eq 0 ]]; then
echo "no match"
exit 1
fi
Do not pattern-match on the absence of a Name in the table output; it is not a parseable format.
Pinning versions in CI
Reproducible pipelines require pinning both the CLI and (optionally) the tools. Because tool versions track the CLI's MAJOR.MINOR line by default, pinning the CLI alone usually suffices:
npm install -g @uipath/cli@1.0.0
uip tools install @uipath/orchestrator-tool # resolves to latest 1.0.x
npm install -g @uipath/[email protected]
uip tools install @uipath/orchestrator-tool # resolves to latest 1.0.x
For strict reproducibility across patch levels, also pin tools:
uip tools install @uipath/orchestrator-tool@1.0.2
uip tools install @uipath/[email protected]
See Tools (plugins) — version resolution for the details.
Suppressing interactive prompts
A handful of uip commands are interactive by default when stdout is a TTY:
uip login— prompts for tenant selection if--tenantis not passed.uip skills install/update/uninstall— prompts for the target agent if--agentis not passed.uip completion— prompts to confirm the install path.uip tools search— prompts for a query if none is passed.
In CI these prompts can hang a job. Avoid them by always passing the relevant flags (--tenant, --agent, --print/explicit shell on completion) or by ensuring stdout is not a TTY (most CI runners already take care of this).
Disabling telemetry in CI
Anonymous telemetry is sent to UiPath's Application Insights by default. For air-gapped or strict environments:
export UIPATH_TELEMETRY_DISABLED=1
export UIPATH_TELEMETRY_DISABLED=1
…or point it at your own instance via UIPATH_AI_CONNECTION_STRING. See Installing UiPath CLI — Telemetry.
See also
- Exit codes — the authoritative table.
- Output formats — the envelope and the four formats.
- Global options —
--output,--output-filter,--log-level,--log-file. - Authentication — the three auth flows referenced in the retry pattern above.
- CI/CD recipes — complete platform-specific pipelines.
- Helpful defaults
- Strict shell options
- Branching on exit codes
- Reading values out of the envelope
- Re-authenticating on AuthenticationError (exit 2)
- Polling long-running operations
- Idempotent pipelines
- Separating data from logs
- Handling empty results
- Pinning versions in CI
- Suppressing interactive prompts
- Disabling telemetry in CI
- See also