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
- Fix the identifier to match the Rust field name exactly.
- After renaming any field, grep the crate for its old name in index(...)/scheduled(...) attributes.
- 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
- After renaming any table field, grep for the old ident inside index(...) and scheduled(...) attributes.
- Reference Rust field idents in macro attributes, not on-chain column names.
- Delete index attributes together with the fields they name.
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
- When providing a name, you must also provide the object.
- Cannot convert to : expected bigint, integer number, or…
- Invalid UUID: must be between 0 and `MAX_UUID_BIGINT`
- must specify view accessor, e.g. `#
- scheduled tables must have a `#[primary_key] #[auto_inc]…
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)