FuelLabs/sway · error · anyhow::Error
only Fuel VM is supported for log decoding
Error message
only Fuel VM is supported for log decoding
What it means
decode_log_data dispatches on the ProgramABI enum and only implements the Fuel variant (ProgramABI::Fuel -> decode_fuel_vm_log_data). Any other variant (e.g. an EVM ABI) returns this error, because the ABIDecoder/type-application machinery only understands Fuel VM log layouts.
Source
Thrown at forc-util/src/tx_utils.rs:67
Ok(serde_json::to_string_pretty(&receipt_to_json_array)?)
} else {
Ok(serde_json::to_string(&receipt_to_json_array)?)
}
}
/// A `LogData` decoded into a human readable format with its type information.
pub struct DecodedLog {
pub value: String,
}
pub fn decode_log_data(
log_id: &str,
log_data: &[u8],
program_abi: &ProgramABI,
) -> anyhow::Result<DecodedLog> {
match program_abi {
ProgramABI::Fuel(program_abi) => decode_fuel_vm_log_data(log_id, log_data, program_abi),
_ => Err(anyhow::anyhow!(
"only Fuel VM is supported for log decoding"
)),
}
}
pub fn decode_fuel_vm_log_data(
log_id: &str,
log_data: &[u8],
program_abi: &fuel_abi_types::abi::program::ProgramABI,
) -> anyhow::Result<DecodedLog> {
let program_abi =
fuel_abi_types::abi::unified_program::UnifiedProgramABI::from_counterpart(program_abi)?;
// Create type lookup (id, TypeDeclaration)
let type_lookup = program_abi
.types
.iter()
.map(|decl| (decl.type_id, decl.clone()))View on GitHub (pinned to 47e5e902fa)
Solutions
- Build/run the project for the Fuel VM target so the Fuel JSON ABI is generated
- Pass the Fuel program ABI (from Forc.abi.json) to the decoding call
- If you wrap this API, early-match on ProgramABI::Fuel and give a clearer message for other targets
Example fix
// before
let decoded = decode_log_data(log_id, &data, &evm_abi)?;
// after
let ProgramABI::Fuel(fuel_abi) = &fuel_abi else {
bail!("log decoding requires a Fuel program ABI");
};
let decoded = decode_log_data(log_id, &data, &ProgramABI::Fuel(fuel_abi.clone()))?; Defensive patterns
Strategy: type-guard
Validate before calling
if !matches!(program_abi, ProgramABI::Fuel(_)) {
anyhow::bail!("log decoding requires a Fuel VM program ABI");
}
let decoded = decode_log_data(log_id, log_data, program_abi)?; Type guard
fn is_fuel_abi(abi: &ProgramABI) -> bool {
matches!(abi, ProgramABI::Fuel(_))
} Try / catch
let decoded = match decode_log_data(log_id, log_data, program_abi) {
Ok(d) => d,
Err(e) if e.to_string().contains("only Fuel VM") => {
anyhow::bail!("non-Fuel target: raw log data is {}", hex::encode(log_data))
}
Err(e) => return Err(e),
}; Prevention
- Standardize on Fuel program ABIs (Forc.abi.json) for all decode paths
- Assert the ABI flavor before any decoding loop over receipts
When it happens
Trigger: Calling forc_util::tx_utils::decode_log_data with a ProgramABI whose discriminant is not Fuel — concretely when a non-Fuel program ABI is passed to decode a LogData receipt during forc run/test log printing.
Common situations: Experimental/multi-VM toolchains that emit EVM-flavored ABIs, or tooling that constructs ProgramABI from the wrong JSON schema and lands in the non-Fuel arm.
Related errors
- log id is missing
- {}: file not found
- Incomplete bytecode
- Configurables section offset not found
- Serialized receipts does not contain {} th index
AI-assisted analysis of FuelLabs/sway@47e5e902fa (2026-08-16).
Data as JSON: /api/errors/92c4f884bbbc6af3.
Report an issue: GitHub.