unionlabs/union · error
rawValue too short for a selector: {}
Error message
rawValue too short for a selector: {} What it means
send_and_expect_revert extracted a hex string from the revert error, but after stripping 0x it holds fewer than 8 hex digits (4 bytes), the minimum length of a Solidity revert selector. The transaction did revert, but the captured hex is not selector-shaped (e.g. a short rawValue like 0x01 or a non-selector hex fragment matched earlier in the error string), so the first-4-bytes selector comparison is meaningless and the helper bails.
Source
Thrown at tools/union-test/src/lib.rs:1050
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}`")
})?;
if actual == expected_revert_code {
Ok(())
} else {
anyhow::bail!(
"Expected selector 0x{:08x}, got 0x{:08x} (raw: {})",
expected_revert_code,
actual,
hex_full
)
}
}View on GitHub (pinned to 031785bb6d)
Solutions
- Look at the raw error string in the message: identify what the short hex actually is and whether the real selector appears later.
- If the contract genuinely reverts with a short code, don't use send_and_expect_revert's selector matching — assert on the raw value or use a different check.
- Tighten the regex to require at least 8 hex digits, e.g. (0x[0-9A-Fa-f]{8,}), so short tokens are skipped.
- Update the contract test fixture to revert with a proper custom error selector.
Example fix
// before — matches any hex token, including 2-char ones
let re = Regex::new(r"(0x[0-9A-Fa-f]+)").unwrap();
// after — only selector-shaped hex can match
let re = Regex::new(r"(0x[0-9A-Fa-f]{8,})").unwrap(); Defensive patterns
Strategy: validation
Validate before calling
// pre-check shape before slicing
anyhow::ensure!(hexdigits.len() >= 8, "raw value {hex_full} has no selector ({} hex digits)", hexdigits.len()); Type guard
fn is_selector_shaped(hex_full: &str) -> bool {
let d = hex_full.trim_start_matches("0x");
!d.is_empty() && d.chars().all(|c| c.is_ascii_hexdigit()) && d.len() >= 8
} Prevention
- Require {8,} hex digits in the regex so short flags/gas values never match.
- Make contracts revert with custom errors (4-byte selectors) in tests rather than bare require flags.
When it happens
Trigger: Contract reverts via require with a bare short value (common: 0x00/0x01 flags) instead of a custom Error(string)/selector; or the regex matched a short incidental hex token (address of 1-2 chars never, but gas values like 0x1f can appear) before the real rawValue; revert with empty data plus stray short hex in the message.
Common situations: Cosmos-wasm style contract errors surfaced as short hex codes; minimal require(cond) reverts with no message; provider error text containing a small hex number (e.g. block 0x5) that the greedy regex grabs first.
Related errors
- Transaction reverted but no rawValue hex found: {}
- Expected selector 0x{:08x}, got 0x{:08x} (raw: {})
- Expected revert 0x{:08x}, but transaction succeeded
- not implemented
- not implemented
AI-assisted analysis of unionlabs/union@031785bb6d (2026-08-16).
Data as JSON: /api/errors/0e5a024f56cdaf9b.
Report an issue: GitHub.