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
- Print/inspect the full err_str ({:#} chain) that the error message embeds — it shows whether the failure was a revert or an infrastructure error.
- If the failure was infra (network/timeout), fix connectivity and rerun; the revert path itself is fine.
- 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.
- 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
- Pin the provider crate version whose error Display includes the raw revert hex.
- Prefer typed accessors for revert data over string scraping when the provider exposes them.
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
- rawValue too short for a selector: {}
- Expected revert 0x{:08x}, but transaction succeeded
- Expected selector 0x{:08x}, got 0x{:08x} (raw: {})
- not implemented
- not implemented
AI-assisted analysis of unionlabs/union@031785bb6d (2026-08-16).
Data as JSON: /api/errors/0ee46b7b7005afd4.
Report an issue: GitHub.