paritytech / paritytech/polkadot-cli
feat: structured exit codes and pipe-friendly output for scripted workflows
Nobody has claimed this yet.
- Dominant language
- TypeScript
- Stars
- 10
- Forks
- 2
- Avg merge
- 12h 35m
- Merged PRs (30d)
- 4
Description
Context
When the CLI is used by an AI agent or in shell scripts, the caller needs to programmatically determine:
- Did the command succeed or fail?
- What kind of failure occurred?
- What was the meaningful output?
Currently, the CLI exits with process.exit(1) on all errors and outputs human-readable text. While --output json helps with parsing, there's no structured way to distinguish between different failure modes, and some output goes to stderr vs stdout inconsistently.
Proposal
1. Structured Exit Codes
Define meaningful exit codes that scripts/agents can branch on:
| Code | Meaning | Example |
|---|---|---|
0 |
Success | Transaction finalized, query returned data |
1 |
General/unknown error | Unexpected crash |
2 |
Usage error | Invalid arguments, missing required flags |
3 |
Connection error | RPC unreachable, timeout connecting |
4 |
Transaction dispatch error | Extrinsic executed but dispatch failed (e.g., InsufficientBalance) |
5 |
Transaction rejected | Not included in block (e.g., invalid nonce, fee too low) |
6 |
Query returned null/empty | Storage item doesn't exist for the given key |
7 |
Chain/metadata error | Pallet not found, call not found |
2. JSON Error Output
With --output json, errors should also be JSON:
{
"error": true,
"code": 4,
"type": "dispatch_error",
"message": "Balances.InsufficientBalance",
"details": {
"pallet": "Balances",
"error": "InsufficientBalance",
"txHash": "0xabc..."
}
}
Currently errors are console.error() text which is hard to parse programmatically.
3. Consistent stdout/stderr Separation
- stdout: Only the meaningful result data (JSON, values, hashes)
- stderr: Progress spinners, status messages, warnings, errors
This enables clean piping:
# Pipe query result to jq
dot query ProofOfInk.Candidates <acct> --chain people --output json 2>/dev/null | jq '.type'
# Chain commands based on exit code
dot query ProofOfInk.Candidates <acct> --chain people --output json 2>/dev/null
if [ $? -eq 6 ]; then
echo "No candidacy found, need to apply"
dot tx ProofOfInk.apply --from candidate --chain people
fi
4. --quiet Flag
Suppress all non-essential output (spinners, status messages, explorer links). Only output the core result:
# Just the raw value, nothing else
dot query System.Number --chain polkadot --output json --quiet
# Output: 12345678
# Just success/failure for tx
dot tx ProofOfInk.apply --from candidate --chain people --quiet
# Output: {"txHash":"0x...","block":1234,"status":"ok"}
Current State
From src/cli.ts, all errors go through:
} catch (error) {
if (error instanceof CliError) {
console.error(chalk.red(`Error: ${error.message}`));
} else {
console.error(chalk.red(`Error: ${error}`));
}
process.exit(1);
}
Everything exits with code 1 regardless of error type.
Implementation Notes
- Map
CliErrorsubclasses to exit codes (or add anexitCodeproperty toCliError) - For
dot queryreturning null/undefined: exit with code6instead of printing empty output with code0 - For
dot txdispatch errors: already detected intx.tsline ~186, just need to set the right exit code - Progress spinners already go to stderr via
ora(good), but some informational output may go to stdout --quietflag: skip explorer links, skip event listings, skip decode display
Why This Matters for Agent Workflows
An AI agent calling CLI commands via Bash tool can:
- Check
$?exit codes to branch logic without parsing output text - Parse
--output jsonerrors structurally instead of regex-matching error messages - Use
--quietto reduce output noise when only the result matters - Pipe
--output jsonto other tools reliably
This turns the CLI from a human-interactive tool into a proper building block for automated workflows.
Labels
enhancement, agent-readiness
Contributor guide
No contributing guide indexed for this repository
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start with the error handler in src/cli.ts and the dispatch-error handling around line 186 of tx.ts. Trace how query and transaction commands currently report results, errors, and progress, then map the proposed exit codes, JSON errors, stream separation, and --quiet behavior across those entry points. Done means scripted workflows can distinguish the listed outcomes and consume clean output.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- typescript
- Domain
- cli
- Issue type
- Feature
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 35/100