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
- Send the numeric chain id string (e.g. "2" for testing) in `txn_params.chain_id`
- Pre-validate with `ChainId::from_str` and return a client-side error
- 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
- Always send chain_id as a numeric string, not a network name
- Trim whitespace from config-derived values
- Check ChainId::try_from(u8) docs for the correct value (e.g. 2 = testing)
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.