{"record":{"id":"92c4f884bbbc6af3","repo":"FuelLabs/sway","slug":"only-fuel-vm-is-supported-for-log-decoding","errorCode":null,"errorMessage":"only Fuel VM is supported for log decoding","messagePattern":"only Fuel VM is supported for log decoding","errorType":"console","errorClass":"anyhow::Error","httpStatus":null,"severity":"error","filePath":"forc-util/src/tx_utils.rs","lineNumber":67,"sourceCode":"        Ok(serde_json::to_string_pretty(&receipt_to_json_array)?)\n    } else {\n        Ok(serde_json::to_string(&receipt_to_json_array)?)\n    }\n}\n\n/// A `LogData` decoded into a human readable format with its type information.\npub struct DecodedLog {\n    pub value: String,\n}\n\npub fn decode_log_data(\n    log_id: &str,\n    log_data: &[u8],\n    program_abi: &ProgramABI,\n) -> anyhow::Result<DecodedLog> {\n    match program_abi {\n        ProgramABI::Fuel(program_abi) => decode_fuel_vm_log_data(log_id, log_data, program_abi),\n        _ => Err(anyhow::anyhow!(\n            \"only Fuel VM is supported for log decoding\"\n        )),\n    }\n}\n\npub fn decode_fuel_vm_log_data(\n    log_id: &str,\n    log_data: &[u8],\n    program_abi: &fuel_abi_types::abi::program::ProgramABI,\n) -> anyhow::Result<DecodedLog> {\n    let program_abi =\n        fuel_abi_types::abi::unified_program::UnifiedProgramABI::from_counterpart(program_abi)?;\n\n    // Create type lookup (id, TypeDeclaration)\n    let type_lookup = program_abi\n        .types\n        .iter()\n        .map(|decl| (decl.type_id, decl.clone()))","sourceCodeStart":49,"sourceCodeEnd":85,"githubUrl":"https://github.com/FuelLabs/sway/blob/47e5e902faa42baf652dd6a0c88cd23390c1a614/forc-util/src/tx_utils.rs#L49-L85","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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"],"exampleFix":"// before\nlet decoded = decode_log_data(log_id, &data, &evm_abi)?;\n\n// after\nlet ProgramABI::Fuel(fuel_abi) = &fuel_abi else {\n    bail!(\"log decoding requires a Fuel program ABI\");\n};\nlet decoded = decode_log_data(log_id, &data, &ProgramABI::Fuel(fuel_abi.clone()))?;","handlingStrategy":"type-guard","validationCode":"if !matches!(program_abi, ProgramABI::Fuel(_)) {\n    anyhow::bail!(\"log decoding requires a Fuel VM program ABI\");\n}\nlet decoded = decode_log_data(log_id, log_data, program_abi)?;","typeGuard":"fn is_fuel_abi(abi: &ProgramABI) -> bool {\n    matches!(abi, ProgramABI::Fuel(_))\n}","tryCatchPattern":"let decoded = match decode_log_data(log_id, log_data, program_abi) {\n    Ok(d) => d,\n    Err(e) if e.to_string().contains(\"only Fuel VM\") => {\n        anyhow::bail!(\"non-Fuel target: raw log data is {}\", hex::encode(log_data))\n    }\n    Err(e) => return Err(e),\n};","preventionTips":["Standardize on Fuel program ABIs (Forc.abi.json) for all decode paths","Assert the ABI flavor before any decoding loop over receipts"],"tags":["forc-util","abi","log-decoding","fuel-vm"],"backgroundTag":null,"analyzedSha":"47e5e902faa42baf652dd6a0c88cd23390c1a614","analyzedAt":"2026-08-16T07:57:45.555Z","schemaVersion":2},"datasetVersion":"2026-08-16T08:17:34.114Z"}