clockworklabs/SpacetimeDB · error · Error
Uint8Array is not 32 bytes long
Error message
Uint8Array is not 32 bytes long: [${array}] What it means
#[spacetimedb::table] derives the SATS type via sats_type_from_derive and then requires SatsTypeData::Product — only structs can be tables, because a table needs a fixed set of columns. Enums and unions produce Sum data, so the derive bails with a call-site span.
Solutions
- Make the item a struct with one field per column.
- For variant values without table semantics, use #[derive(SpacetimeType)] on the enum and reference it as a column type in a struct table.
- If variants must be queryable, model them as rows with a discriminator column.
Example fix
// before
#[spacetimedb::table(accessor = shape)]
enum Shape { Circle { r: f64 }, Square { a: f64 } }
// after
#[derive(SpacetimeType)]
enum Shape { Circle { r: f64 }, Square { a: f64 } }
#[spacetimedb::table(accessor = shape)]
struct ShapeRow { #[auto_inc] id: u64, shape: Shape } Defensive patterns
Strategy: validation
Prevention
- Only apply #[spacetimedb::table] to structs; use plain SpacetimeType derives for enums/unions.
- When converting a table struct into another kind of item, remove the table attribute in the same commit.
When it happens
Trigger: Annotating an enum or union with #[spacetimedb::table(...)] — the else-branch on the SatsTypeData match fires.
Common situations: Trying to make a tagged-union table; a struct converted to an enum while the table attribute stayed; misunderstanding that tables are row types, not variant types.
Related errors
- Cannot convert to : expected bigint, integer number, or…
- Invalid UUID: must be between 0 and `MAX_UUID_BIGINT`
- UUID v4 requires 16 bytes
- When providing a name, you must also provide the object.
- When providing a name, you must also provide the variants…
AI-assisted analysis of clockworklabs/SpacetimeDB@6dee26c6ef (2026-08-20).
Data as JSON: /api/errors/6c94273e412a1418.
Report an issue: GitHub.
Appendix: source
Thrown at crates/bindings-typescript/src/lib/util.ts:55
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))
);
return data.reverse();
}
export function hexStringToU128(str: string): bigint {
return uint8ArrayToU128(hexStringToUint8Array(str));
}View on GitHub (pinned to 6dee26c6ef)