Repository navigation
Releases: paritytech/polkadot-cli
Release list
v1.25.1
What's Changed
- chore: refresh built-in RPC endpoints by @peetzweg in #318
- chore: version packages by @github-actions[bot] in #319
Full Changelog: v1.25.0...v1.25.1
v1.25.0
What's Changed
- chore: refresh built-in RPC endpoints, drop decommissioned IBP by @peetzweg in #288
- chore(deps): safe in-range bumps + ws security override by @peetzweg in #291
- feat: negotiate the highest supported metadata version instead of pinning v15 by @peetzweg in #298
- fix: let --ext override builtin extensions, error on unknown names by @peetzweg in #297
- feat: select the transaction-extension version from metadata by @peetzweg in #299
- docs: showcase tapes for the README and docs site by @peetzweg in #302
- docs: record the remaining showcase tapes by @peetzweg in #304
- Rename
--unsignedto--general(deprecated alias kept) by @peetzweg in #307 - Upgrade polkadot-api to 3.0 by @peetzweg in #308
- fix: unknown command crashed with 'Bun is not defined' under node by @peetzweg in #309
- chore(deps): upgrade verifiablejs 1.4.0 -> 1.6.0 by @peetzweg in #311
- fix: output errors as JSON when --json is passed by @CiprianPotor in #312
- feat: every error honours --json; add DOT_OUTPUT env var by @peetzweg in #313
- chore: version packages by @github-actions[bot] in #290
New Contributors
- @CiprianPotor made their first contribution in #312
Full Changelog: v1.24.0...v1.25.0
v1.24.0
What's Changed
- chore: update repository references from peetzweg to paritytech by @peetzweg in #281
- Surface the active config root in chain commands by @peetzweg in #280
- feat(skill): first-class Codex support via
dot skillby @peetzweg in #282 - chore: version packages by @github-actions[bot] in #283
Full Changelog: v1.23.0...v1.24.0
v1.22.0
What's Changed
- feat(account): add rm alias for account delete/remove by @peetzweg in #242
- fix(cli): stop dropping --help for nested subcommands (#238) by @peetzweg in #244
- fix(cli): make nested --help survive the production bundle (#238) by @peetzweg in #248
- feat: global DOT_DRY_RUN flag to force dry-run on all extrinsics by @peetzweg in #243
- chore(deps): upgrade polkadot-api to 2.1.7 by @peetzweg in #256
- chore(deps): upgrade verifiablejs to 1.4.0 by @peetzweg in #257
- docs: document {relay}-{parachain} chain naming convention by @peetzweg in #262
- ci: publish via paritytech/npm_publish_automation by @peetzweg in #266
- chore(deps): upgrade cac from 6 to 7 by @peetzweg in #268
- chore: version packages by @github-actions[bot] in #245
Full Changelog: v1.21.0...v1.22.0
v1.21.0
Minor Changes
-
5ac2b5e: Add directory-local workspaces:
dot initcreates a.polkadot/workspace in the current directory, discovered git-style (cwd and parents, stopping at$HOME) and fully isolating accounts, custom chains, and metadata cache from the global~/.polkadot. Newdot whichshows the active config root and how it was chosen. Precedence:DOT_HOME→ local workspace → global. Account and chain resolution errors now name the config root that was searched. -
a33128e: feat(verifiable): ring-VRF proof, signing, verification and members primitives
Adds composable
dot verifiablesubcommands oververifiablejs:verifiable sign/verify-sig— standalone Bandersnatch signatures.verifiable alias— derive the alias for a 32-byte ring context.verifiable prove/verify— ring-VRF proofs (one_shot) and local
verification against a members set or a 768-byte ring root.verifiable members— SCALE-encode member keys asVec<[u8;32]>.
The command is scoped to raw verifiable crypto only — bytes in, bytes out, with
no chain/pallet knowledge and no automated fetching or selection (the same way
dot signis just sr25519). Supply the members/context/message yourself (e.g.
read from chain withdotfirst) and use the resulting signature/proof however
you need — in adotextrinsic or signed extension, or elsewhere.All actions accept hex /
--file/--stdininput and--output json, and a
newsrc/features/verifiable/lib.tsexposes the underlying primitives for reuse.Breaking: the entropy-derivation key is now
--entropy-key(was--context
ondot verifiable), and--contextnow means the 32-byte ring/proof namespace
— aligning with the runtime (type Context = [u8;32]) and the iOS/Android
clients. The old--context <key>form still works on the member command for one
release with a deprecation warning; switch to--entropy-key.
Patch Changes
-
09aab3e: fix(tx): show stale-metadata hint on
BadProof/AncientBirthBlockwithStalenessSuggestionalready wraps everysignSubmitAndWatchcall
and, on error, compares cached(specVersion, transactionVersion, codeHash)against the live runtime — if they diverge it appends the
⚠ Local metadata for "<chain>" is out of date … Run: dot chain update <chain>hint. But the gating regex only matched wasm-trap / codec /
decode symptoms, notInvalid::BadProoforInvalid::AncientBirthBlock.After a chain runtime upgrade the signer used the cached spec/tx
version, the runtime reconstructed a different payload, the signature
didn't verify and the tx was rejected with a bareBadProof— leaving
the user guessing. The fingerprint mismatch was right there but the
regex skipped over it.CheckSpecVersion/CheckTxVersion/CheckGenesis/
CheckMortalityare all in the signed payload, soBadProofand
AncientBirthBlockare exactly the variants that smell like stale
metadata. Adding them to the pattern list lets the existing fingerprint
gate run; if cached matches live (genuine bad key / wrong chain) the
raw error still passes through unchanged.Nonce-mismatch variants (
Future,Stale) are deliberately excluded —
those are account-state issues, not metadata. -
c1ed560: fix(completions): only print setup instructions when stdout is a TTY
dot completions <shell>wrote its setup hint to stderr on every invocation.
Insideeval "$(dot completions zsh)"in~/.zshrc, stderr bypasses the
command substitution and reaches the terminal, so every new shell printed the
# Add this to your ~/.zshrcblock. The hint is now only printed when stdout
is a TTY — i.e. when a human runs the command to look at the script — and
stays silent when the output is captured byevalor redirected to a file. -
d9a27d7: fix(test): make polkadot-api module mocks ordering-safe across test files
No runtime behavior change — this fixes the flaky CI failures where
createChainClienttests failed depending on test-file scheduling order.
bun'smock.module()is global to the test process and not restored between
files, soclient.test.tsandload-meta.test.tsclobbered each other's
mocks. Both now share a fixture that spreads the real module exports into
the mocks and captures the realcreateChainClientbefore any file can stub
theclient.tsmodule.
v1.20.0
Minor Changes
-
5920098: feat(account): reveal mnemonic with
--show-secretand import raw private keysdot account inspect <name> --show-secretnow also reveals the stored
mnemonic (or 32-byte hex seed) alongside the 64-byte sr25519 expanded private
key, in both text and--jsonoutput. Env-backed secrets stay redacted — only
the$VARreference is shown.dot account add <name> --secret 0x<128 hex>now imports an account directly
from a 64-byte sr25519 expanded secret — the exact value--show-secret
prints — making it round-trippable. Imported expanded-secret accounts sign and
resolve addresses like any other signer. A derivation path cannot be applied to
an expanded secret, so--pathis rejected for this format.Fixes a related bug:
--secret 0x...was previously corrupted bycac's
numeric coercion, so 32-byte hex seed import never worked from the command
line. The raw argv value is now read directly, so both hex seeds and raw
private keys import correctly. The misleading "hex seed not supported" help text
has been corrected.
Patch Changes
-
0dd979c: chore(deps): upgrade
polkadot-apito2.1.4and sibling@polkadot-api/*packagesBumps
polkadot-api(2.0.1 → 2.1.4),@polkadot-api/metadata-builders
(0.14.1 → 0.14.3),@polkadot-api/substrate-bindings(0.20.1 → 0.20.3),
@polkadot-api/view-builder(0.5.1 → 0.5.3), and
@polkadot-api/metadata-compatibility(0.6.1 → 0.6.3, dev).
Minor/patch bumps with no API surface change in the parts consumed by the CLI. -
6535199: chore(deps): upgrade
verifiablejsto1.3.0Bumps
verifiablejsfrom1.3.0-beta.2to the stable1.3.0release. The JS
API consumed by the CLI (member_from_entropy) is unchanged, but the release
bumps the underlyingverifiablecrate to v0.5.0 (ThinVRF, new ring proofs),
so derived Bandersnatch member keys are wire-incompatible withbeta.2—
this is the intended alignment with theverifiablecrate used on-chain by
individuality. Updated the documented example keys (README, docs) and added a
regression test pinning alice's derived member keys to the 1.3.0 wire format.
v1.19.0
Minor Changes
-
64bc0b5: fix(query, apis): honor
--at <block>for historical reads--atwas declared on the global command but only ever wired intotx
submission.query.*andapis.*accepted the flag silently and read
current head anyway, making historical state reads and per-block runtime
API replays impossible from the high-level wrappers.papi v2 supports historical reads natively via the trailing
PullOptions
argument on storage and runtime calls ({ at: "best" | "finalized" | <hash> }). The fix threads the flag through.-
dot polkadot.query.System.Number --at best -
dot polkadot.query.System.Number --at finalized -
dot polkadot.query.System.Number --at 0x<hash> -
dot polkadot.apis.Core.version --at 0x<hash>Behavior matrix:
Command --at best--at finalized--at 0x<hash>query.*✓ ✓ ✓ apis.*✓ ✓ ✓ tx.*rejected (papi v2 constraint) ✓ ✓ Also fixes a pre-existing CAC/mri argv-parsing bug where 0x-hex block
hashes passed to--atwere silently coerced to JS Numbers, losing
precision.--atis now read from raw argv to keep the original string
intact.papi v2's
chainHead_v1_*JSON-RPC only serves pinned (recent) blocks.
For deep historical reads, point--rpcat an archive endpoint.
-
-
debed0d: feat(account): show pallet-revive H160 in
dot account inspectEvery Substrate account now also shows its pallet-revive 20-byte H160
address (EIP-55 checksummed) on theH160:line, so developers working
across SS58 and EVM tooling on Polkadot Hub / Asset Hub can see both
representations side by side. The same H160 appears under theh160
field of--output json.The mapping is offline and matches current
polkadot-sdkmaster:- AccountId32 → H160: if the last 12 bytes are
0xEE, strip them
(the account originated from an Eth address); otherwise
keccak256(accountId32)and take the last 20 bytes. - H160 → AccountId32: deterministic fallback
H160 || 0xEE * 12.
The full mapping afterpallet_revive.map_accountlives in on-chain
AddressSuffixstorage and is not recoverable offline.
dot account inspectaccepts a 20-byte H160 hex value as a new input
form. It resolves to the fallback AccountId32 and reports
Kind: revive H160 fallback.dot account inspect alice # H160: 0x9621DDe636dE098B43Efb0fA9b61fAcFE328F99D dot account inspect 0x9621DDe636dE098B43Efb0fA9b61fAcFE328F99D # Kind: revive H160 fallback # Public Key: 0x9621dde636de098b43efb0fa9b61facfe328f99deeeeeeeeeeeeeeeeeeeeeeee dot account inspect alice --json | jq -r .h160 # 0x9621DDe636dE098B43Efb0fA9b61fAcFE328F99D
Older
stable2412runtimes used plainaccountId32[..20]truncation
instead of the keccak fallback for the forward direction. A
--revive-truncateflag for those is not implemented; this release
ships only the canonical current-master mapping. - AccountId32 → H160: if the last 12 bytes are
-
ecd453b: feat(hash): add
twox64,twox128,twox256algorithmsSubstrate uses XXH64-based
twox*hashes throughout — pallet/storage prefixes
aretwox128(palletName) ++ twox128(itemName), andTwox64Concatis a common
storage-map hasher. Previouslydot hashonly supported the BLAKE2b, Keccak,
and SHA-2 families, so constructing a raw storage key required an external
tool.The three new algorithms are pure-TypeScript (no wasm, no native deps) and
verified against canonical XXH64 vectors and Substrate prefixes:dot hash twox128 System→0x26aa394eea5630e07c48ae0c9558cef7dot hash twox128 Balances→0xc2261276cc9d1f8598ea4b6a74b15c2fdot hash twox64 <key>/dot hash twox256 <key>for the other variants
Combined with
dot [chain.]rpc.state_getStorage 0x<key>, this is enough to
read any raw storage value, including the well-known keys (:code,
:heappages) that live outside metadata.
Patch Changes
-
47992bf: fix(errors): friendlier message when
--at <block>is not availableWhen
--atpoints at a block the connected RPC can't serve — most often
an old hash against a non-archive node — papi raises
BlockHashNotFoundError/StorageError: UnknownBlock/ "is not pinned"
rejections. These now get caught at thequery.*/apis.*/tx.*
call sites and re-surfaced as a cleanCliErrorwith a copy-pasteable
hint:Error: Block 0x… is not pinned (storage) ⚠ 0x… is not available on the current RPC endpoint. Public nodes serve only recent (pinned) blocks via chainHead_v1_*. For deep historical reads, point --rpc at an archive endpoint, e.g.: dot ... --at 0x… --rpc wss://<archive-endpoint>Note: papi's substrate-client may still emit its own internal stack
trace ahead of the clean message; suppressing that is a separate
follow-up. -
a801337: chore(deps): upgrade
verifiablejsto1.3.0-beta.2Tracks the upstream beta. The CLI only consumes
member_from_entropy,
whose signature is unchanged, sodot verifiableoutput is byte-identical.
v1.18.0
Minor Changes
-
0a4c5f3: feat(rpc): add
dot [chain.]rpc.<method>for raw JSON-RPC callsCloses #196.
Substrate nodes expose a JSON-RPC surface (
system_*,chain_*,state_*,
author_*,payment_*, consensus and dev families, plus the new spec
chainSpec_v1_*/archive_v1_*/rpc_methods) that is separate from
runtime metadata and was previously unreachable from this CLI.The new
rpccategory mirrors the other dotpath commands: methods are
discovered per-chain viarpc_methods, cached at
~/.polkadot/chains/<chain>/rpc-methods.json, and tab-completed.dot polkadot.rpc— list methods grouped by familydot polkadot.rpc.system_health— call a methoddot polkadot.rpc.chain_getBlock 0x<hash>— positional argsdot polkadot.rpc.<method> --help— curated description and arg names
for ~50 well-known methods; raw passthrough for the restdot polkadot.rpc --refresh— re-discover methods on a node upgrade
Subscription methods (
*_subscribe*,chainHead_v1_follow,transaction_v1_*)
appear in completion but error out as one-shots with a helpful message.dot chain addanddot chain updatenow also fetch and cache the method
list, anddot chain infoshows a per-family breakdown. -
3180e75: Add derivation flags to
dot account addthat store sovereign addresses as named watch-only accounts. One command lets you turn a parachain ID or a palletPalletIdinto a stored account that's reusable in--from, in tx args, and indot account list.# Pallet sovereign (Treasury / Bounties / Crowdloan / NominationPools / …) dot account add Treasury --pallet-id py/trsry dot account add Bounties --pallet-id 0x70792f626f756e74 # Parachain sovereign — type is required (child = address on the relay, # sibling = address from another parachain's POV) dot account add People --parachain 1004 --parachain-type child dot account add People-Sibling --parachain 1004 --parachain-type sibling
Derivation (matches Substrate's
AccountIdConversion::into_account_truncating):- Pallet:
b"modl"(4 bytes) +palletId(8 bytes) + 20 zero bytes - Parachain:
b"para"(child) orb"sibl"(sibling) + paraId LE u32 (4 bytes) + 24 zero bytes
PalletId input is either 8 ASCII chars (
py/trsry) or 0x-prefixed hex with exactly 16 hex chars (0x70792f7472737279). Per-chain PalletIds can be discovered via the existingconstcategory:dot account add Treasury --pallet-id "$(dot polkadot.const.Treasury.PalletId | tr -d '"')"Constraints:
--parachainrequires--parachain-type child|sibling(no implicit default);--parachainand--pallet-idare mutually exclusive; derivation flags cannot be combined with a positional address or with--secret/--env.JSON output (
--json) includes aderivationobject describing the source —{ "kind": "pallet", "palletId": "py/trsry", "palletIdHex": "0x..." }or{ "kind": "parachain", "paraId": 1004, "type": "child" }— for round-trippable record-keeping.dot account listis restructured to make kinds obvious and SS58s easier to copy-paste. Stored accounts are now bucketed into Signers, Watch-only, Pallet Sovereigns, and Parachain Sovereigns sections (empty sections omitted). The first line of each entry is justname ss58; extra attributes render on tree-style continuation lines (├─/└─, mirroringdot chains). Attribute labels are aligned with the--flagthat sets each value (path:,env:,pallet-id:,parachain:,parachain-type:) so the listing reads back as a recipe. Multiple attributes per account (e.g.--path+--env) each get their own branch:Signers ci-signer 5DAAnrj7VHTznn2AWBemMuyBwZWs6FNFjdyVXUeYum3PTXFy ├─ path: //ci └─ env: $CI_SECRET Pallet Sovereigns Treasury 5EYCAe5ijiYfyeZ2JJCGq56LmPyNRAKzpG4QkoQkkQNB5e6Z └─ pallet-id: py/trsry (0x70792f7472737279) Parachain Sovereigns People 5Ec4AhPaYcfBz8fMoPd4EfnAgwbzRS7np3APZUnnFo12qEYk ├─ parachain: 1004 └─ parachain-type: child--jsonadds akinddiscriminator on every entry plus asourceobject on derived sovereigns.dot account inspectnow surfaces the derivation source. The output gains aKind:line (dev/signer/watch-only/pallet sovereign/parachain sovereign (child|sibling)) and, for derived sovereigns, aSource:line (PalletId py/trsry (0x70792f7472737279)orparachain 1004). For env-backed signers there's anEnv:line; derived child keys show theirDerivation:path.Storage-format change:
StoredAccountgains an optionalsourcefield that records how a watch-only account was derived. Existing accounts without this field continue to work — they're classified as plainsignerorwatch-onlybased on the presence of a secret.dot account inspectaccepts the same derivation flags for stateless lookup. When you just need the SS58 in a script and don't want a stored entry, rundot account inspect --pallet-id <id>ordot account inspect --parachain <id> --parachain-type <child|sibling>— same output shape (Kind / Source / SS58 / public key, plus a structuredsourceobject on--json), no name, nothing written to~/.polkadot/accounts.json.SS58=$(dot account inspect --pallet-id py/trsry --prefix 0 --json | jq -r .ss58)Use
account addto persist (named, reusable as--from/ tx arg / inaccount list); useaccount inspectto derive ad-hoc. - Pallet:
Patch Changes
-
34044e8: Preserve the standalone
dot parachain <paraId>command as a deprecated alias.The same release that introduced sovereign-account derivation flags on
dot account(--parachain/--parachain-type/--pallet-id) had also deleted the older standalonedot parachaincommand. To avoid breaking production scripts that pin the prior CLI surface, the command is restored verbatim — same arguments, same exit codes, same byte-identical stdout for--jsonand pretty output. It now prints a one-line deprecation warning to stderr only, so pipes intojq/awk/ file redirects keep working unchanged.Migrate at your convenience:
# Before dot parachain 1000 --type child --json # After (same SS58 / public key, structured `source` field on JSON output) dot account inspect --parachain 1000 --parachain-type child --json
Tracked for removal in a future release: #208.
v1.17.0
Minor Changes
-
fd6cf14: Clean up
dot chainsoutput and adddot chain info <name>for per-chain detail.dot chainsis now scannableThe default
dot chains(anddot chain list) output no longer prints RPC URLs inline. The list view becomes a compact tree of names + relay structure + parachain IDs:Configured Chains polkadot ├─ polkadot-asset-hub [1000] ├─ polkadot-bridge-hub [1002] ├─ polkadot-collectives [1001] ├─ polkadot-coretime [1005] └─ polkadot-people [1004] paseo ├─ paseo-asset-hub [1000] └─ paseo-people [1004]Pass
-v/--verbose(à lagit remote -v) to keep the previous behavior with RPC endpoints inline:dot chains -v dot chain list --verbose
dot chain info <name>A new
infoaction prints full per-chain detail in one block — RPC endpoints, relay/parachain id, child parachains (when the target is a relay), and metadata cache status:dot chain info polkadot # polkadot # # rpc: # wss://polkadot.ibp.network # wss://rpc.polkadot.io # ... # parachains: # polkadot-asset-hub [1000] # polkadot-bridge-hub [1002] # ... # metadata: # polkadot v1003000 (cached 2026-04-29T12:34:56.000Z)
dot chain <name>is a bare-noun shortcut that falls through tochain info <name>— likegh repo view. The dispatcher still pattern-matches known action verbs first (add,remove,update,list,export,import), so existing usage is unchanged.--jsonemits a structured object withname,rpc[], optionalrelay/parachainId, optionalparachains[], and ametadatablock (ornullwhen no fingerprint is cached). Names resolve case-insensitively, matchingfindChainNamesemantics used elsewhere.When metadata has never been fetched for the chain, the metadata row prints
not cached — run \dot chain update `` so it's clear how to populate it. -
ede4b8c: Width-aware multi-line pretty-printing for type signatures, call arguments, and decoded calls.
dot inspect, the focused listings (dot <chain>.tx.<Pallet>,.query.<Pallet>,.events.<Pallet>,.extensions), and--dry-runoutput now render structured types across multiple lines when they don't fit, with syntactic ANSI coloring (field names cyan, primitives yellow, container keywords magenta, enum variants green). Short signatures stay compact.Before
Args: (proposal_origin: system | Origins | ParachainsOrigin | XcmPallet, proposal: Legacy | Inline | Lookup, enactment_moment: At | After)After
Args: ( proposal_origin : system | Origins | ParachainsOrigin | XcmPallet, proposal : Legacy | Inline | Lookup, enactment_moment: At | After, )Storage detail now shows
Type:,Key:, andValue:on separate lines (no→arrow), with composite values expanded:Assets.Metadata (Storage) Type: map Key: u32 Value: { deposit : u128, name : Vec<u8>, symbol : Vec<u8>, decimals : u8, is_frozen: bool, }Dry-run
Decode:is now JSON-styled, suitable for very complex calls:Decode: System.remark { "remark": "0x68656c6c6f20776f726c64" }Enum variant visibility — the
enum(N variants)summary threshold was raised from 4 to 24, so most enums (e.g.Option<AsPersonalAliasWithAccount | AsPersonalAliasWithProof | ...>) now show variant names instead of being collapsed.Width detection uses
process.stdout.columns(falls back to 80). Output is automatically uncolored when stdout isn't a TTY, so piped--jsonand shell-redirected output stay clean.JSON output (
--json) is unchanged — type strings continue to be emitted as compact single-line values for scripting.
Patch Changes
-
3a12d97: Fix
dot query <Pallet.Item> --dump --json | jqfailing with
jq: parse error: Unfinished JSON term at EOFon populated storage maps
(reported againstpolkadot-asset-hub query.Revive.AccountInfoOf).# Now works (previously truncated past ~64 KiB of output): dot --chain polkadot-asset-hub query.Revive.AccountInfoOf --dump --json | jq
Bun's
console.logwrites toprocess.stdoutare async, and the CLI returns
before the userspace stdout buffer drains into the OS pipe; on Linux
(~64 KiB pipe buffer) anything past that threshold gets dropped. PR #194
fixed this fordot metadatawith a local awaitable-write helper. This
extracts that helper intosrc/core/output.tsas a sharedwriteStdout
primitive and routesdot query's five output sites through it (the
--dumpmap-entries path that triggers the user's bug, the single-value
fetch, and the three pallet/storage listing paths).dot metadatanow
imports the shared helper instead of carrying its own copy.Issue #198 stays open as the forward-looking sweep —
inspect,const,
apis, etc. still emit viaconsole.log, but their payloads don't
realistically cross the pipe-buffer threshold today, so they're left for
when (or if) one of them grows.
v1.16.0
Minor Changes
-
e4ee0dc: Add
dot metadata <chain>command and detect stale local metadata after a failed call.dot metadata <chain>A new top-level command that fetches a chain's runtime metadata and prints it as a single JSON blob with everything needed to drive the chain — pallets (with calls, events, errors, storage, constants), runtime APIs, transaction extensions, and a runtime fingerprint header (
specVersion,transactionVersion,codeHash, etc.). Closes #170.dot metadata polkadot # decoded JSON, fetched fresh from the chain dot metadata polkadot --raw # SCALE-encoded metadata bytes as a single 0x… hex line dot metadata polkadot --cached # use locally cached metadata, skip the network round-trip dot metadata polkadot --rpc wss://… # override the RPC endpoint
Stale-metadata suggestion
When
dot tx,--dry-run, ordot queryfails with an error that smells like stale metadata (a runtime wasm trap, codec/decode failure, or fee-estimation panic), the CLI now compares your local metadata's runtime fingerprint against the live chain. If it has changed, the original error is wrapped with a one-line suggestion telling you exactly which command to run:Error: The runtime rejected this transaction in the runtime's validate_transaction step. Cause: a runtime invariant failed — typically the call's arguments are out of range, … ⚠ Local metadata for "paseo-people-next" is out of date (spec 1018 → 1020). Run: dot chain update paseo-people-nextThe fingerprint includes the runtime code hash (from
state_getStorageHash(":code:")) — so the check also catches local-node restarts where the runtime wasm changed butspecVersionwas kept the same. No automatic refetch happens; the suggestion is shown once and the original error still propagates with the non-zero exit code.The check only fires on suspected-stale errors, so the happy path pays no extra RPC. Set
DOT_TRUST_CACHED_METADATA=1to skip the check entirely (e.g. for CI or scripted loops where you've just refreshed manually).Companion improvements
formatRuntimeErrornow translates raw polkadot-api wasm-trap stack traces into a friendly "the runtime rejected this transaction" message with a hint pointing at--dry-run.dot tx --dry-runnow surfaces the underlying reason when fee estimation fails (previously the error message was silently dropped, leaving only "unable to estimate").- A global
unhandledRejectionfilter swallows benign late-timer rejections from@polkadot-api/observable-client(Not connected,DisjointError) that previously crasheddot chain update --allafter the actual work had completed.
Patch Changes
-
e4ee0dc: Friendlier error output when the runtime panics or papi cleanup races leak.
Runtime wasm traps
Errors from inside
validate_transaction(wasmunreachableinstruction /Execution aborted due to trap) used to be printed as a verbatim wasm backtrace from polkadot-api. They now render as a one-paragraph "the runtime rejected this transaction" message that names the failing entrypoint where possible (e.g.the runtime's validate_transaction step) and points at--dry-runfor the next step.--dry-runno longer hides the reason fee estimation failedPreviously
dot tx … --dry-runswallowed any exception fromgetEstimatedFeesand printed onlyEstimated fees: unable to estimate. The error reason is now captured and displayed alongside the estimate (and included in the JSON output asestimationError), so users see why estimation failed before deciding to submit.dot chain update --allno longer crashes on cleanup races@polkadot-api/observable-clientschedules timers inside its chain-head follow stream that can fire afterclient.destroy()has cleared the connection, rejecting withError: Not connectedorDisjointError. Previously these unhandled rejections killed the process after the actual update work had completed. Aprocess.on('unhandledRejection')filter at the CLI entry point now swallows that specific class of teardown noise (matched by name) and lets unrelated rejections through with the new friendlier formatting.