§ Reference · Commands
Global flags, environment and exit codes
The flags every pravo command accepts, the flags several commands share, the debug log, JSON output, the environment variables and where the exit codes are listed.
On this page
Quick reference
Global flags
These flags belong to the command pravo and every subcommand accepts them.
| Flag | Default | Meaning |
|---|---|---|
-C, --chdir DIR |
none | Run as if started in DIR. Relative paths in other flags, such as --policy, are relative to DIR. |
--no-color |
off | Do not colour the output. Colour is used only on a terminal. |
-v |
off | Log what pravo decides and does to stderr. See The debug log. |
-vv |
off | Finer detail, and the log of the providers. |
--json |
off | Machine-readable output on stdout, progress on stderr. See JSON. |
--actor LABEL |
$PRAVO_ACTOR |
A label for who is acting. Recorded on transactions, locks, reservations and plans. It is not verified. |
--reason TEXT |
$PRAVO_REASON |
Why. Recorded with the actor. |
-h, --help |
Print the help of the command. |
pravo help COMMAND prints the same help. pravo completion bash, zsh, fish or powershell prints a completion script for that shell.
Flag syntax
A long flag takes one dash or two: -auto-approve and --auto-approve are the same flag. -v repeated, -vv, is the verbose flag twice. A value follows = or a space, except for --refresh of plan, apply and destroy, where the value follows = only. --refresh alone means all, so in -refresh false the word false is an argument.
A command that takes no argument refuses a word, so a misplaced value is an error with exit code 1. Write the value of --refresh with =. See A word after a flag.
Flags that several commands share
| Flag | Commands | Meaning |
|---|---|---|
-t, --tag key=value |
init, plan, apply, destroy, output, import, providers, gen, validate, eval, schema, why, drift, state and each of its subcommands |
Inject a value into the field tagged @tag(key). Repeatable. |
-T, --inject-vars |
the same | Inject the system variables of CUE into tags written @tag(name,var=os). Examples are os, arch and username. |
--refresh=age|expired|false|all |
plan, apply, destroy, why |
When to read real state from the providers. See pravo plan. |
--full |
plan, apply |
Plan every resource with its provider. |
--policy FILE |
plan, apply, destroy, mcp |
A CUE file the plan must satisfy. Repeatable. |
pravo show, pravo fmt, pravo version and pravo mod take no tags. Use the same tags for plan and apply. Otherwise they evaluate different specifications. A saved plan carries its own.
pravo output has its own --json flag that replaces the global one.
Examples
Work in an empty directory named demo.
package app
import rnd "pravo.dev/providers/hashicorp/random"
$random: rnd.#Provider
base: $random.#Resource.random_integer & {min: 1, max: 9, seed: "base"}
Another directory
Success! 1 resources, 0 data sources, 0 ephemeral, 0 function calls, 0 outputs across 1 providers.
A word after a flag
--refresh takes its value only after =. Without it the flag means all, and the next word is an argument. plan takes none, so it refuses the word:
Error: pravo plan takes no arguments, but got "false"; write the value of -refresh with =, as in -refresh=false
The debug log
-v writes pravo's own account of a run to stderr. It says what was loaded, where each provider version came from, which state was opened and how the graph was built. For each task it gives the action and the reason. Each line starts with the time since the command began. Nothing is printed without -v.
+0.000s debug loaded dir=./app managed=1 data=0 ephemeral=0 calls=0 outputs=0 providers=1 moves=0 imports=0 took=<time>
+0.000s debug state opened backend=local location=./app/pravo.state nodes=0 took=<time>
+0.000s debug plan refresh=age full=false destroy=false tasks=1
+0.000s debug graph built tasks=1 took=<time>
+0.000s debug task addr=base phase=plan outcome=ok took=<time> action=create why="not in the state: a new resource"
The task line carries the reasons that pravo why prints. Values of attributes are never logged. The name of an environment variable is logged and its value is not.
-vv adds the finest detail: the dependencies of each task and when it starts. It also turns on the log of the providers, which is off otherwise.
+0.000s trace graph node addr=base deps=
+0.000s trace task start addr=base phase=plan deps=
PRAVO_LOG=debug or trace does the same as -v or -vv for pravo, and sets the level of the log of the providers. info, warn and error affect the log of the providers only.
JSON
With --json, stdout holds JSON and nothing else. Human progress lines go to stderr.
| Command | stdout |
|---|---|
plan, show, why, drift, state show, state log, state locks, providers, validate, schema, mod list, mod verify |
One JSON document. |
state query |
The value as JSON. |
apply, destroy |
Newline-delimited events, and a summary line last. |
mcp |
Not affected. The server speaks JSON-RPC. |
An error prints {"code":N,"kind":"error","message":"..."} on stdout, where N is the exit code, and the text of the error on stderr.
{"code":1,"kind":"error","message":"open missing.plan: no such file or directory"}
Error: open missing.plan: no such file or directory
apply and destroy emit one event per step. A plain apply with changes to make needs --auto-approve with --json, since nobody can answer the prompt. An event has these fields; those marked "if set" are left out when empty.
| Field | Content |
|---|---|
time |
When the event happened, in UTC. |
kind |
refresh, read, open, call, create, update, replace, destroy, lock, note, plan or apply. |
phase |
start, done, skip or error. |
addr, message, id, elapsed_ms, trace_id |
The address of the resource, the line a person reads, the provider id, the duration in milliseconds, and the trace id (each if set). |
txn |
The transaction. |
The event of kind plan carries the plan document. The last event, of kind apply, has added, changed, destroyed, outputs, planfile and remaining. pravo apply shows events.
A string is written as it is: <, > and & are not escaped as \u003c, \u003e and \u0026. That holds for the commands above, for pravo output --json, for the events of apply and destroy, and for the messages of pravo mcp. A list with no entries is [] and never null. The root text declares one output and no resource:
package text
import "pravo.dev/pravo"
link: pravo.#Output & {value: "https://example.com/?a=1&b=<2>"}
{
"link": "https://example.com/?a=1&b=<2>"
}
[]
{
"ok": true,
"problems": []
}
Actor and reason
--actor and --reason are labels. pravo records them and does not check them. They appear in pravo state log, in pravo state locks, in pravo show and in the plan document. An actor also owns the reservations it takes; without a label, the operating system user owns them.
<txn> apply applied <time>
pravo -C app apply --auto-approve --actor ci --reason first apply
actor ci first apply
1 added, 0 changed, 0 destroyed
create base r0 -> r1
Record and replay
PRAVO_RECORD=DIR records every response of the providers during a run. PRAVO_REPLAY=DIR answers the requests of a run from such a recording, without starting a provider. A recorded plan or apply can be replayed in a pipeline without credentials. A request that was not recorded fails with a message that says so.
random
No changes. Your infrastructure matches the configuration.
Graph: planned 0 of 1, 1 unchanged and skipped, 1 refreshed.
A recording holds the values the provider returned: the attributes of your objects, the sensitive ones included, and the results of ephemeral resources. Handle it like state. pravo creates the directory of each provider with mode 0700 and each file with mode 0600, and it does not write the values of a request. The provider configuration, which carries the credentials, and the write-only attributes are therefore not in the recording. A request is recorded as its method and its type, name or version.
every directory has mode 0700
every file has mode 0600
{"method":"Configure","request":{}}
Copying a recording, or keeping it in version control, does not keep the modes. Store it where you store state. CI uses a recording in a pipeline.
Environment variables
| Variable | Meaning |
|---|---|
PRAVO_HOME |
Where providers and cached schemas are kept. Default ~/.pravo. |
PRAVO_LOG |
trace, debug, info, warn or error. See The debug log. |
PRAVO_S3_PROBE |
off skips the check that an S3 store honours conditional requests. See S3-compatible stores. |
PRAVO_ACTOR, PRAVO_REASON |
The values of --actor and --reason when the flags are absent. |
PRAVO_RECORD, PRAVO_REPLAY |
A directory to record provider responses to, or to replay them from. |
NO_COLOR |
When set, the output is not coloured. |
CUE_REGISTRY |
The registry for CUE modules. When it is set, pravo uses it as it is. See pravo mod. |
TF_PLUGIN_CACHE_DIR |
An OpenTofu plugin cache from which pravo init takes a provider before it downloads one. |
TF_REATTACH_PROVIDERS |
The reattach information of a provider that already runs. pravo connects to it and does not start or stop it. |
OTEL_*, TRACEPARENT, TRACESTATE |
OpenTelemetry settings and the trace to continue. See Telemetry. |
Exit codes
Every command exits with 0, 1, 2, 3, 4, 5 or 6. Exit codes gives the meaning of each code and runs a command that ends with it. Under --json an error also prints {"code":N,"kind":"error","message":"..."} on standard output. The tools of pravo mcp return the same codes in structuredContent.exit_code.