Skip to content

AssetHubKusama types bundle: TAssetConversion / Option<Location> fails to decode V5 cross-consensus assetId #6256

Description

@brenzi

disclaimer: agent-created report. but human reproduced and confirmed the issue

Summary

Decoding a V5 cross-consensus Location (e.g. bridged-from-Polkadot USDC on
Asset Hub Kusama: parents:2, X4[GlobalConsensus(Polkadot), Parachain(1000), PalletInstance(50), GeneralIndex(1337)]) fails when it arrives via the
assetId field of a SignerPayloadJSON for AssetHubKusama (which the chain's
pallet_asset_conversion_tx_payment resolves through TAssetConversion
Option<Location>):

createType(ExtrinsicPayload):: createType(TAssetConversion)::
decodeU8aStruct: failed at 0x090200a10f043205e514… on interior (index 2/2):
{"_enum":{"Here":"Null","X1":"[JunctionV5;1]","X2":"[JunctionV5;2]",
          "X3":"[JunctionV5;3]","X4":"[JunctionV5;4]","X5":"[JunctionV5;5]",
          "X6":"[JunctionV5;6]","X7":"[JunctionV5;7]","X8":"[JunctionV5;8]"}}::
Unable to create Enum via index 9, in Here, X1, X2, X3, X4, X5, X6, X7, X8      

The decoder reads parents=02 and Junctions::X4=04, then for the
[JunctionV5; 4] payload it reads 0x09 (which is the inner
Junction::GlobalConsensus variant) as a fresh outer Junctions variant
byte. Junctions only has variants Here, X1..X8 (indices 0–8), so index 9 is
out of range and decoding aborts.

The bytes themselves are well-formed runtime-valid SCALE; the chain accepts
them, and a tx that includes them in ChargeAssetTxPayment.value = 0x00010204090200a10f043205e514 runs fine. PAPI also encodes / decodes them
correctly. The failure is specifically in TAssetConversion's type resolution
for AssetHubKusama.

Reproduction

import { ApiPromise, WsProvider } from '@polkadot/api';
                                            
const api = await ApiPromise.create({   
  provider: new WsProvider('wss://kusama-asset-hub-rpc.polkadot.io'),
});                                                                             
                                        
// bridged-from-Polkadot USDC on KAH (V5 cross-consensus Location)              
const assetId = '0x0204090200a10f043205e514';                                   
                                        
api.createType('TAssetConversion', assetId);    // throws "Unable to create Enum
 via index 9"                                                                   
// or, equivalently, via the path the extensions exercise:
// api.createType('ExtrinsicPayload', { ..., assetId, ... })                    

Real-world impact

This is hit by every dApp using pallet_asset_conversion_tx_payment on
AssetHubKusama with a bridged asset as the fee asset. The polkadot.js extension
and SubWallet both crash their signing popups on the resulting
SignerPayloadJSON, and the React error boundary doesn't recover — every
subsequent signing prompt in the session also shows the error screen until the
browser is fully restarted.

Downstream issues with full traces, sticky-state details, and a npx serve .
HTML reproduction:

Suggested fix area

  • Verify the AssetHubKusama types bundle has JunctionV5 (singular) registered
    with all V5 variants — including GlobalConsensus(StagingXcmV5NetworkId) at
    index 9 — so '[JunctionV5;4]' resolves to the correct inner type and the
    decoder reads each X4 payload entry as a Junction rather than a fresh
    Junctions.
  • Confirm TAssetConversion for chains where
    pallet_asset_conversion_tx_payment::Config::AssetId = Location resolves to
    Option<StagingXcmV5Location>, not an older MultiLocation.
  • Adding a regression test that round-trips a cross-consensus Location (with
    parents:2 and a GlobalConsensus junction) through TAssetConversion for
    AssetHubKusama / AssetHubPolkadot would prevent re-introduction.

Environment

  • Tested chain: Asset Hub Kusama (wss://kusama-asset-hub-rpc.polkadot.io)
  • Runtime spec version: 2002000

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions