unionlabs/union · warning · anyhow::Error
regex matched but capture group missing
Error message
regex matched but capture group missing
What it means
A defensive, effectively unreachable branch in send_and_expect_revert: Regex::captures succeeded (so group 1 exists by construction of the regex (0x[0-9A-Fa-f]+), which has exactly one capturing group), yet caps.get(1) returned None and the code bails with 'regex matched but capture group missing'. In practice you should never see this; hitting it indicates a regex crate version/behavior anomaly or corrupted logic.
Source
Thrown at tools/union-test/src/lib.rs:1046
"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}`")
})?;
if actual == expected_revert_code {
Ok(())
} else {
anyhow::bail!(
"Expected selector 0x{:08x}, got 0x{:08x} (raw: {})",
expected_revert_code,
actual,View on GitHub (pinned to 031785bb6d)
Solutions
- If encountered, check whether the regex literal near lib.rs:1042 was modified to use optional/non-participating groups; restore a single mandatory group.
- Simplify by using re.captures(...).and_then(|c| c.get(1)) and treating both as the 111 case, removing the impossible branch.
- Verify regex crate version in Cargo.lock is the one the code was written for.
Defensive patterns
Strategy: type-guard
Type guard
fn first_capture(caps: ®ex::Captures<'_>) -> Option<&str> {
caps.get(1).map(|m| m.as_str()) // single mandatory group always participates
} Prevention
- Keep exactly one mandatory capture group in the selector regex.
- Cover this parsing with a unit test feeding representative provider error strings.
When it happens
Trigger: Only producible if the regex pattern were edited to include an optional capture group that did not participate in the match, or an incompatible regex crate regression — the current pattern always populates group 1 on a match.
Common situations: Someone modifies the regex to (0x...)?-style optional groups; pathological regex crate downgrade/upgrade. Otherwise this is dead defensive code.
Related errors
- Transaction reverted but no rawValue hex found: {}
- rawValue too short for a selector: {}
- not implemented
- not implemented
- not implemented
AI-assisted analysis of unionlabs/union@031785bb6d (2026-08-16).
Data as JSON: /api/errors/2746f1ab75441a92.
Report an issue: GitHub.