paritytech / paritytech/polkadot-cli

feat: structured exit codes and pipe-friendly output for scripted workflows

Open
#6 0 comments 0 reactions 0 assignees View on GitHub

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:

  1. Did the command succeed or fail?
  2. What kind of failure occurred?
  3. 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 CliError subclasses to exit codes (or add an exitCode property to CliError)
  • For dot query returning null/undefined: exit with code 6 instead of printing empty output with code 0
  • For dot tx dispatch errors: already detected in tx.ts line ~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
  • --quiet flag: 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 json errors structurally instead of regex-matching error messages
  • Use --quiet to reduce output noise when only the result matters
  • Pipe --output json to 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

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. 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

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.