unionlabs/union · error · anyhow::Error

Transaction reverted but no rawValue hex found: {}

Error message

Transaction reverted but no rawValue hex found: {}

What it means

send_and_expect_revert caught an Err from send_ibc_transaction (the expected revert) and tries to extract the raw revert value with the regex (0x[0-9A-Fa-f]+). This error says the transaction did fail, but the formatted error string {:#} of the anyhow chain contains no 0x… hex blob, so no revert selector can be parsed. The revert data got lost in provider formatting or the failure was not an execution revert at all (e.g. network error), so the harness cannot verify the expected selector.

Source

Thrown at tools/union-test/src/lib.rs:1037

        msg: Src::Msg,
        expected_revert_code: u32,
        signer: &Src::ProviderType,
    ) -> anyhow::Result<()> {
        match source_chain
            .send_ibc_transaction(contract.clone(), msg.clone(), signer)
            .await
        {
            Ok((_, _)) => anyhow::bail!(
                "Expected revert 0x{:08x}, but transaction succeeded",
                expected_revert_code
            ),

            Err(e) => {
                let err_str = format!("{:#}", e);

                let re = Regex::new(r"(0x[0-9A-Fa-f]+)").unwrap();
                let caps = re.captures(&err_str).ok_or_else(|| {
                    anyhow!(
                        "Transaction reverted but no rawValue hex found: {}",
                        err_str
                    )
                })?;

                let hex_full = caps
                    .get(1)
                    .map(|m| m.as_str())
                    .ok_or_else(|| anyhow!("regex matched but capture group missing"))?;

                let hexdigits = hex_full.trim_start_matches("0x");
                if hexdigits.len() < 8 {
                    anyhow::bail!("rawValue too short for a selector: {}", hex_full);
                }
                let selector_hex = &hexdigits[..8]; // first 4 bytes

                let actual = u32::from_str_radix(selector_hex, 16).with_context(|| {
                    format!("parsing revert selector `{selector_hex}` from `{hex_full}`")

View on GitHub (pinned to 031785bb6d)

Solutions

  1. Print/inspect the full err_str ({:#} chain) that the error message embeds — it shows whether the failure was a revert or an infrastructure error.
  2. If the failure was infra (network/timeout), fix connectivity and rerun; the revert path itself is fine.
  3. If the provider now formats revert data differently, update the regex to also match bare hex or pull the revert data from the typed provider error instead of string matching.
  4. Pin the provider version whose error formatting this helper was written against.

Example fix

// before — string-scrape the first hex blob
let re = Regex::new(r"(0x[0-9A-Fa-f]+)").unwrap();

// after — prefer typed revert data when available, fall back to regex
let re = Regex::new(r"(?:0x)?([0-9A-Fa-f]{8,})").unwrap();
Defensive patterns

Strategy: try-catch

Try / catch

let e = send_result.unwrap_err();
let err_str = format!("{e:#}");
let sel = extract_selector(&err_str)
    .ok_or_else(|| anyhow!("no revert data in error; raw error was: {err_str}"))?;

Prevention

When it happens

Trigger: The send fails for a non-revert reason (connection reset, timeout, estimation error without revert data) while the test expected an on-chain revert; or the provider version formats revert data without a leading 0x prefix (e.g. bare hex) so the regex misses it.

Common situations: RPC hiccup at the moment the reverting tx is sent; alloy/ethers provider upgrade changing error Display formatting so the rawValue no longer appears; revert with empty data.

Related errors


AI-assisted analysis of unionlabs/union@031785bb6d (2026-08-16). Data as JSON: /api/errors/0ee46b7b7005afd4. Report an issue: GitHub.