diem/diem · error

Failed to convert str to ChainId

Error message

Failed to convert str to ChainId

What it means

`generate_raw_txn` parses the `chain_id` string field with `ChainId::from_str` and panics via `expect` on failure. `ChainId` only parses numeric strings corresponding to known chain IDs, so any non-numeric or out-of-range value aborts the tool.

Source

Thrown at crates/swiss-knife/src/main.rs:221

            new_key_hex_encoded,
        } => {
            let new_url = new_url.into_bytes();
            let new_key = hex::decode(new_key_hex_encoded)
                .expect("Failed to hex decode new_key_hex_encoded field");
            transaction_builder::encode_rotate_dual_attestation_info_script(new_url, new_key)
        }
    };
    let payload = TransactionPayload::Script(script);
    let script_hex = hex::encode(bcs::to_bytes(&payload).unwrap());
    let raw_txn = RawTransaction::new(
        helpers::account_address_parser(&g.txn_params.sender_address),
        g.txn_params.sequence_number,
        payload,
        g.txn_params.max_gas_amount,
        g.txn_params.gas_unit_price,
        g.txn_params.gas_currency_code,
        g.txn_params.expiration_timestamp_secs,
        ChainId::from_str(&g.txn_params.chain_id).expect("Failed to convert str to ChainId"),
    );
    GenerateRawTxnResponse {
        script: script_hex,
        raw_txn: hex::encode(
            bcs::to_bytes(&raw_txn)
                .map_err(|err| {
                    helpers::exit_with_error(format!(
                        "bcs serialization failure of raw_txn : {}",
                        err
                    ))
                })
                .unwrap(),
        ),
    }
}

#[derive(Deserialize, Serialize)]
#[serde(rename_all = "snake_case")]

View on GitHub (pinned to fc4714a8ea)

Solutions

  1. Send the numeric chain id string (e.g. "2" for testing) in `txn_params.chain_id`
  2. Pre-validate with `ChainId::from_str` and return a client-side error
  3. Replace `expect` with error propagation for a cleaner API

Example fix

// before
ChainId::from_str(&g.txn_params.chain_id).expect("Failed to convert str to ChainId"),
// after
ChainId::from_str(g.txn_params.chain_id.trim())
    .map_err(|e| format!("invalid chain_id '{}': {e}", g.txn_params.chain_id))?,
Defensive patterns

Strategy: validation

Validate before calling

fn valid_chain_id(s: &str) -> bool {
    s.trim().parse::<u8>().is_ok()
}

Try / catch

let chain_id = ChainId::from_str(g.txn_params.chain_id.trim())
    .map_err(|e| bad_request(format!("chain_id must be numeric: {e}")))?;

Prevention

When it happens

Trigger: Passing a `chain_id` in the request that is not a plain numeric string (e.g. "mainnet", "TESTING", empty, or with whitespace) to swiss-knife's generate_raw_txn endpoint.

Common situations: Client sends the chain name instead of its numeric ID; trailing newline from config parsing; using a chain id value unsupported by the linked diem types version.


AI-assisted analysis of diem/diem@fc4714a8ea (2026-09-04). Data as JSON: /api/errors/46fa0974387ad569. Report an issue: GitHub.