clockworklabs/SpacetimeDB · error · Error

Uint8Array is not 16 bytes long

Error message

Uint8Array is not 16 bytes long: ${array}

What it means

find_column resolves an identifier used by index arguments (and the scheduled at = ... column) against the table struct's field identifiers. If no field matches, the attribute references a column that does not exist on this table; the syn error is spanned to the offending identifier.

Solutions

  1. Fix the identifier to match the Rust field name exactly.
  2. After renaming any field, grep the crate for its old name in index(...)/scheduled(...) attributes.
  3. Remember the lookup uses field idents, not on-chain column names.

Example fix

// before
pub struct Order { pub state: String }
#[spacetimedb::table(index(btree = [status]))]
                         // ^ no field named `status`

// after
#[spacetimedb::table(index(btree = [state]))]
pub struct Order { pub state: String }
Defensive patterns

Strategy: validation

Prevention

When it happens

Trigger: #[index(btree = [status])] on a table whose field is named state; scheduled(my_reducer, at = run_at) with no run_at field; referencing an on-chain column name (from a column rename attribute) instead of the Rust field ident.

Common situations: Renaming a field without updating index attributes; leftover attributes after deleting a field; using the SATS/on-chain column name where the macro expects the Rust ident.

Related errors


AI-assisted analysis of clockworklabs/SpacetimeDB@6dee26c6ef (2026-08-20). Data as JSON: /api/errors/6f6af5cb61192ca1. Report an issue: GitHub.

Appendix: 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 6dee26c6ef)