clockworklabs/SpacetimeDB · error · Error
Uint8Array is not 16 bytes long: ${array}
Error message
Uint8Array is not 16 bytes long: ${array} What it means
uint8ArrayToU128 interprets the bytes as a little-endian 128-bit integer via BinaryReader.readU128, so exactly 16 bytes are required; any other length throws. It also backs hexStringToU128, so a hex string decoding to the wrong byte count surfaces here too.
Source
Thrown at crates/bindings-typescript/src/lib/util.ts:48
// Check all keys and compare values recursively
for (const key of keys1) {
if (!keys2.includes(key) || !deepEqual(obj1[key], obj2[key])) {
return false;
}
}
return true;
}
export function uint8ArrayToHexString(array: Uint8Array): string {
return Array.prototype.map
.call(array.reverse(), x => ('00' + x.toString(16)).slice(-2))
.join('');
}
export function uint8ArrayToU128(array: Uint8Array): bigint {
if (array.length != 16) {
throw new Error(`Uint8Array is not 16 bytes long: ${array}`);
}
return new BinaryReader(array).readU128();
}
export function uint8ArrayToU256(array: Uint8Array): bigint {
if (array.length != 32) {
throw new Error(`Uint8Array is not 32 bytes long: [${array}]`);
}
return new BinaryReader(array).readU256();
}
export function hexStringToUint8Array(str: string): Uint8Array {
if (str.startsWith('0x')) {
str = str.slice(2);
}
const matches = str.match(/.{1,2}/g) || [];
const data = Uint8Array.from(
matches.map((byte: string) => parseInt(byte, 16))View on GitHub (pinned to 524b4487d9)
Solutions
- Validate array.length === 16 before calling
- Check the source hex string: after stripping '0x' it must be exactly 32 hex chars
- Use the matching converter - uint8ArrayToU256 for 32-byte values
Example fix
// before const v = uint8ArrayToU128(identityBytes); // identityBytes is 32 bytes -> throws // after const v = uint8ArrayToU256(identityBytes); // 32-byte value // or slice the correct 16 bytes: uint8ArrayToU128(identityBytes.slice(0, 16))
Defensive patterns
Strategy: validation
Validate before calling
function isU128Bytes(array: Uint8Array): boolean {
return array.length === 16;
}
// if (!isU128Bytes(bytes)) throw new TypeError(`expected 16 bytes, got ${bytes.length}`); Prevention
- Check length before converting; 16 bytes = u128, 32 bytes = u256
- Validate hex strings: 32 hex chars (after stripping 0x) for u128, 64 for u256
- Centralize byte-width knowledge in one conversion helper per width
When it happens
Trigger: Passing a Uint8Array whose length is not 16 directly, or a hex string that decodes to a non-16-byte array (e.g. a 64-char identity/address hex) through the hex-to-u128 helpers that call this function.
Common situations: Reusing 32-byte Identity/address bytes for a u128 field; slicing arrays with wrong offsets; hex strings with odd length or without zero padding.
Related errors
- Uint8Array is not 32 bytes long: [${array}]
- UUID v4 requires 16 bytes
- Invalid UUID: must be between 0 and `MAX_UUID_BIGINT`
- Index '${indexLabel}' on table '${tableLabel}' must define a
- Timestamp is outside of the representable range of JS's Date
AI-assisted analysis of clockworklabs/SpacetimeDB@524b4487d9 (2026-08-16).
Data as JSON: /api/errors/6f6af5cb61192ca1.
Report an issue: GitHub.