clockworklabs/SpacetimeDB · error · TypeError
When providing a name, you must also provide the object.
Error message
When providing a name, you must also provide the object.
What it means
When validating index arguments in #[spacetimedb::table(index(...))], the macro requires a Direct index column to carry #[unique]. A direct index maps each column value to at most one row, which is only sound for unique columns, so the combination without #[unique] is rejected at derive time.
Solutions
- Add #[unique] to the same column if values are guaranteed distinct.
- If duplicate values must be allowed, use #[index(btree)] or #[index(hash)] instead — they index many rows per key.
- Verify #[unique] sits on the column (field attribute), not on the table.
Example fix
// before
#[spacetimedb::table(index(direct = email))]
pub struct User { #[auto_inc] pub id: u64, pub email: String }
// after
#[spacetimedb::table(index(direct = email))]
pub struct User {
#[auto_inc] pub id: u64,
#[unique] pub email: String, // direct index requires unique
} Defensive patterns
Strategy: validation
Prevention
- Pair every direct index with #[unique] on the same column by habit.
- If duplicates are possible, choose btree or hash indexes instead of direct.
- Review index attributes whenever a column's uniqueness changes.
When it happens
Trigger: Declaring a direct index on a column that is not marked #[unique], e.g. a table with #[index(direct)] (or the direct index form naming that column) but no #[unique] attribute on the field.
Common situations: Adding 'direct' for fast point lookups without realizing it implies uniqueness; removing #[unique] during a refactor while keeping the direct index.
Related errors
- Cannot convert to : expected bigint, integer number, or…
- Invalid UUID: must be between 0 and `MAX_UUID_BIGINT`
- Uint8Array is not 16 bytes long
- Uint8Array is not 32 bytes long
- UUID v4 requires 16 bytes
AI-assisted analysis of clockworklabs/SpacetimeDB@6dee26c6ef (2026-08-20).
Data as JSON: /api/errors/9609e7eee6085c49.
Report an issue: GitHub.
Appendix: source
Thrown at crates/bindings-typescript/src/lib/type_builders.ts:3913
* @returns A new {@link F64Builder} instance
*/
f64: (): F64Builder => new F64Builder(),
/**
* Creates a new `Product` {@link AlgebraicType} to be used in table definitions. Product types in SpacetimeDB
* are essentially the same as objects in JavaScript/TypeScript.
* Properties of the object must also be {@link TypeBuilder}s.
* Represented as an object with specific properties in TypeScript.
*
* @param name (optional) A display name for the product type. If omitted, an anonymous product type is created.
* @param obj The object defining the properties of the type, whose property
* values must be {@link TypeBuilder}s.
* @returns A new {@link ProductBuilder} instance.
*/
object: ((nameOrObj: any, maybeObj?: any) => {
if (typeof nameOrObj === 'string') {
if (!maybeObj) {
throw new TypeError(
'When providing a name, you must also provide the object.'
);
}
return new ProductBuilder(maybeObj, nameOrObj);
}
return new ProductBuilder(nameOrObj, undefined);
}) as {
<Obj extends ElementsObj>(name: string, obj: Obj): ProductBuilder<Obj>;
// TODO: Currently names are not optional
// <Obj extends ElementsObj>(obj: Obj): ProductBuilder<Obj>;
},
/**
* Creates a new `Row` {@link AlgebraicType} to be used in table definitions. Row types in SpacetimeDB
* are similar to `Product` types, but are specifically used to define the schema of a table row.
* Properties of the object must also be {@link TypeBuilder} or {@link ColumnBuilder}s.
*
* You can represent a `Row` as either a {@link RowObj} or an {@link RowBuilder} type whenView on GitHub (pinned to 6dee26c6ef)