FuelLabs/fuels-rs · error

is there

Error message

is there

What it means

While mapping a reverted transaction to an Error, if the LogDecoder's error_codes contains the revert id but the ErrorDetails carries no log_id, the SDK assumes the static message msg is present and clones it. The expect fires when the registered ErrorDetails has neither log_id nor msg, an internal invariant violation of the error metadata extracted from the contract ABI.

Source

Thrown at packages/fuels-core/src/types/tx_status.rs:136

    }

    fn map_revert_error(
        receipts: Arc<Vec<Receipt>>,
        reason: &str,
        revert_id: Option<u64>,
        log_decoder: Option<&LogDecoder>,
    ) -> Error {
        if let (Some(revert_id), Some(log_decoder)) = (revert_id, log_decoder)
            && let Some(error_detail) = log_decoder.get_error_codes(&revert_id)
        {
            let error_message = if error_detail.log_id.is_some() {
                log_decoder
                    .decode_last_log(&receipts)
                    .unwrap_or_else(|err| {
                        format!("failed to decode log from require revert: {err}")
                    })
            } else {
                error_detail.msg.clone().expect("is there")
            };

            let reason = format!(
                "panicked at: `{}` - `{}:{}:{}` with message `{}`",
                error_detail.pkg,
                error_detail.file,
                error_detail.line,
                error_detail.column,
                error_message
            );

            return Error::Transaction(Reason::Failure {
                reason,
                revert_id: Some(revert_id),
                receipts,
            });
        }

View on GitHub (pinned to d9a250a518)

Solutions

  1. Clean and rebuild the contract (forc build --release) so the binary and ABI come from the same compilation, then re-run abigen!
  2. Align forc and fuels versions per the SDK version table
  3. Delete stale out/ directories before rebuilding
  4. If it persists with matched versions, open an issue including the revert id and contract source

Example fix

# before: stale artifacts (ABI from an older build than the binary)
cargo test

# after: rebuild both together, then regenerate bindings
forc build --release
# re-run abigen! against out/release/*-abi.json
cargo test
Defensive patterns

Strategy: validation

Validate before calling

# (shell) rebuild binary + ABI from one compilation before decoding reverts
forc build --release
# then re-run abigen! against the fresh out/release/*-abi.json

Try / catch

// for the normal (non-panicking) revert path, match on the structured error:
match err {
    fuels::core::types::errors::Error::Transaction(
        fuels::core::types::errors::Reason::Failure { reason, revert_id, .. },
    ) => {
        eprintln!("revert_id={revert_id:?} reason={reason}");
    }
    _ => {}
}

Prevention

When it happens

Trigger: A contract require! revert whose error code is registered with msg: None and log_id: None, typically because the contract binary and the ABI used for abigen! were produced by mismatched forc/SDK versions or different compilations.

Common situations: Contract compiled with a different forc than the one paired with the SDK; stale build artifacts (old ABI next to a new binary); mixed forc build caches.

Related errors


AI-assisted analysis of FuelLabs/fuels-rs@d9a250a518 (2026-08-16). Data as JSON: /api/errors/aa69bebf4549e459. Report an issue: GitHub.