FuelLabs/fuels-ts · error · FuelError
ENCODE_ERROR
ENCODE_ERROR
Error message
Invalid ${this.baseType}. What it means
Thrown by NumberCoder.encode() when the underlying toBytes()/bn() call fails to convert the input value into a byte array. NumberCoder encodes Sway unsigned integers (u8, u16, u32); if the value is not a valid numeric representation, the conversion throws and this ENCODE_ERROR wraps it. The message includes the baseType (e.g. 'u8') to identify which integer coder rejected the value.
Source
Thrown at packages/abi-coder/src/encoding/coders/NumberCoder.ts:46
constructor(
baseType: NumberCoderType,
options: EncodingOptions = {
padToWordSize: false,
}
) {
const length = options.padToWordSize ? WORD_SIZE : getLength(baseType);
super('number', baseType, length);
this.baseType = baseType;
this.options = options;
}
encode(value: number | string): Uint8Array {
let bytes;
try {
bytes = toBytes(value);
} catch (error) {
throw new FuelError(ErrorCode.ENCODE_ERROR, `Invalid ${this.baseType}.`);
}
if (bytes.length > this.encodedLength) {
throw new FuelError(ErrorCode.ENCODE_ERROR, `Invalid ${this.baseType}, too many bytes.`);
}
return toBytes(bytes, this.encodedLength);
}
decode(data: Uint8Array, offset: number): [number, number] {
if (data.length < this.encodedLength) {
throw new FuelError(ErrorCode.DECODE_ERROR, `Invalid number data size.`);
}
const bytes = data.slice(offset, offset + this.encodedLength);
if (bytes.length !== this.encodedLength) {
throw new FuelError(ErrorCode.DECODE_ERROR, `Invalid number byte data size.`);View on GitHub (pinned to b3f37c91ac)
Solutions
- Ensure the value is a finite number or a valid numeric/hex string before calling encode().
- If the field is genuinely nullable, declare it as Option<T> in the Sway ABI so OptionCoder is used instead of NumberCoder.
- Validate with Number.isFinite() or a BN conversion check at the application boundary before encoding.
Example fix
// before
const coder = new NumberCoder('u32');
coder.encode(maybeUndefined); // throws ENCODE_ERROR
// after
const coder = new NumberCoder('u32');
const val = maybeUndefined ?? 0;
if (!Number.isFinite(val)) throw new Error('Expected a finite number');
coder.encode(val); Defensive patterns
Strategy: validation
Validate before calling
function isValidNumberInput(value: unknown): boolean {
if (typeof value === 'number') return Number.isFinite(value);
if (typeof value === 'string') {
const trimmed = value.trim();
if (trimmed === '') return false;
return !isNaN(Number(trimmed));
}
return false;
} Type guard
function isNumberInput(value: unknown): value is number | string {
if (typeof value === 'number') return Number.isFinite(value);
if (typeof value === 'string') {
const t = value.trim();
return t !== '' && !isNaN(Number(t));
}
return false;
} Try / catch
try {
const encoded = numberCoder.encode(value);
} catch (e) {
if (e instanceof FuelError && e.code === ErrorCode.ENCODE_ERROR) {
// value was not a valid number; log and provide default
}
throw e;
} Prevention
- Default optional number fields to 0 instead of leaving them undefined.
- Use Option<T> in the Sway ABI for genuinely nullable numeric fields.
- Validate numeric inputs at the application boundary before ABI encoding.
When it happens
Trigger: Calling NumberCoder('u8').encode(undefined), passing NaN from a failed parseInt, providing a non-numeric string like 'abc', or passing an object. Also triggered indirectly when encoding a struct or tuple whose numeric field is undefined and the field coder is a NumberCoder.
Common situations: An optional struct field is left undefined but the ABI type is a bare u32 (not Option<u32>). A value arrives from JSON as a string containing non-numeric characters. Arithmetic produces NaN that flows into encode().
Related errors
AI-assisted analysis of FuelLabs/fuels-ts@b3f37c91ac (2026-08-12).
Data as JSON: /api/errors/ace1eaa4c75bb3e9.
Report an issue: GitHub.