FuelLabs/sway · error
abi_encode_size_hint for [{}]
Error message
abi_encode_size_hint for [{}] What it means
TypeInfo::abi_encode_size_hint computes how large the abi-encode buffer for a type must be. Primitives, numeric widths, b256, arrays, string arrays, tuples, structs, enums, aliases and potentially-infinite types (slices, raw ptrs, refs, unknowns, error recovery) all have arms; every remaining TypeInfo variant falls into the catch-all unimplemented! that prints the offending type with engines.help_out. In this sway version the unhandled variants are the contract/contract-caller and unresolved Custom types (see the TODO at sway issue #5727 in the source about custom AbiEncode impls).
Source
Thrown at sway-core/src/type_system/info.rs:1660
Some(old_size_hint) => Some(old_size_hint.min(current_size_hint)),
None => Some(current_size_hint),
}
})
.unwrap_or(AbiEncodeSizeHint::Exact(0));
let max =
decl.variants
.iter()
.fold(AbiEncodeSizeHint::Exact(0), |old_size_hint, v| {
let variant_type = engines.te().get(v.type_argument.type_id);
let current_size_hint = variant_type.abi_encode_size_hint(engines);
old_size_hint.max(current_size_hint)
});
AbiEncodeSizeHint::range_from_min_max(min, max) + 8
}
x => unimplemented!("abi_encode_size_hint for [{}]", engines.help_out(x)),
}
}
/// Returns a [String] representing the type.
/// When the type is monomorphized and does not contain [TypeInfo::Custom] types,
/// the returned string is unique.
/// Two monomorphized types that do not contain [TypeInfo::Custom] types,
/// that generate the same string can be assumed to be the same.
pub fn get_type_str(&self, engines: &Engines) -> String {
use TypeInfo::*;
match self {
Unknown => "unknown".into(),
Never => "never".into(),
UnknownGeneric { name, .. } => name.to_string(),
Placeholder(_) => "_".into(),
TypeParam(param) => format!("typeparam({})", param.name()),
StringSlice => "str".into(),
StringArray(length) => {View on GitHub (pinned to 47e5e902fa)
Solutions
- Read the type printed in the message between the brackets - it names the exact unsupported TypeInfo - and remove or replace that field.
- Convert contract addresses to Bits256/Address/B256 (plain 32-byte types with arms) before embedding them in an encoded struct.
- Annotate generics with concrete types so nothing reaches encoding as unresolved Custom.
- Upgrade sway; size-hint coverage and custom AbiEncode impl detection have improved since the referenced TODO.
Example fix
// before
struct Msg { to: ContractId, amount: u64 } // ContractId-containing encode fails
// msg.abi_encode()
// after
struct Msg { to: b256, amount: u64 } // b256 has Exact(32) hint
// Msg { to: to.into(), amount }.abi_encode() Defensive patterns
Strategy: type-guard
Validate before calling
// Sway-side: before encoding, ensure the value's type contains only supported kinds. // Supported: bool, u8..u64, u256, b256, numeric, arrays/str-arrays/tuples/structs/enums/aliases // of supported types. Unsupported: contract, contract caller, unresolved custom/generic.
Type guard
// Rust-side helper for tooling that inspects Sway types before abi_encode:
fn is_abi_size_hint_safe(ti: &TypeInfo, engines: &Engines) -> bool {
use TypeInfo::*;
match ti {
Boolean | UnsignedInteger(_) | Numeric | B256 => true,
Unknown | UnknownGeneric{..} | ErrorRecovery(_) | Ref{..} | Slice(_)
| RawUntypedSlice | StringSlice | RawUntypedPtr | Ptr(_) => true, // PotentiallyInfinite arms
Alias{..} | Array{..} | StringArray(_) | Tuple(_) | Struct(_) | Enum(_) => true,
// everything else (Contract, ContractCaller, Custom, ...) -> false
_ => false,
}
} Try / catch
// unimplemented! panics; catch_unwind at the boundary if you invoke the compiler:
let r = std::panic::catch_unwind(|| value.abi_encode());
if r.is_err() { /* report unsupported type inside the encoded value */ } Prevention
- Never embed contract/contract-caller types in structs you abi_encode; convert to b256 first.
- Keep encoded message types to primitives, arrays, tuples, structs, enums.
- Resolve all generics to concrete types before encoding.
- On compiler errors, read the TypeInfo printed in brackets to find the offending field.
When it happens
Trigger: Calling .abi_encode() (or any API that needs the size hint, such as padded encodes) on a value whose type is, or transitively contains, a TypeInfo variant without a size-hint arm - e.g. a ContractCaller or contract type stored in a struct/enum/tuple being encoded.
Common situations: Encoding a config/message struct that accidentally includes a contract caller or contract id wrapper; generics left unresolved (Custom) reaching encoding; code that worked with plain Address/B256 breaking after swapping in ContractId/contract types.
Related errors
- The allocator cannot resolve a register mapping for this pro
- The allocator cannot resolve a register mapping for this pro
- Arrays in storage have not been implemented yet.
- Stack size too big for these many arguments, cannot handle.
- Too many arguments, cannot handle.
AI-assisted analysis of FuelLabs/sway@47e5e902fa (2026-08-16).
Data as JSON: /api/errors/4c9c85c0d7eeabdf.
Report an issue: GitHub.