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

  1. Make the item a struct with one field per column.
  2. For variant values without table semantics, use #[derive(SpacetimeType)] on the enum and reference it as a column type in a struct table.
  3. 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

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


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)