clockworklabs/SpacetimeDB · error · TypeError
Index '${idx.sourceName ?? '<unknown>'}' on table '${tableDe
Error message
Index '${idx.sourceName ?? '<unknown>'}' on table '${tableDef.sourceName}' is missing accessor name What it means
When schema.ts converts the host-facing RawTableDef into the client-side TableToSchema, it builds fully-resolved runtime index metadata and requires every tableDef.indexes[i].accessorName to be a non-empty string, else it throws a TypeError naming the index and table. Because this metadata is produced by the host toolchain, a missing accessorName almost always means the defs came from an older or mismatched producer.
Source
Thrown at crates/bindings-typescript/src/lib/schema.ts:117
AccName extends string,
const T extends UntypedTableSchema,
>(
accName: AccName,
schema: T,
tableDef: RawTableDefV10
): TableToSchema<AccName, T> {
const getColName = (i: number) =>
schema.rowType.algebraicType.value.elements[i].name;
type AllowedCol = keyof T['rowType']['row'] & string;
// Build fully-resolved runtime index metadata from the host-facing RawTableDef.
// This is intentionally separate from `schema.idxs`, which keeps the original
// user-declared `IndexOpts` shape for type-level inference.
const resolvedIndexes: UntypedIndex<AllowedCol>[] = tableDef.indexes.map(
idx => {
const accessorName = idx.accessorName;
if (typeof accessorName !== 'string' || accessorName.length === 0) {
throw new TypeError(
`Index '${idx.sourceName ?? '<unknown>'}' on table '${tableDef.sourceName}' is missing accessor name`
);
}
const columnIds =
idx.algorithm.tag === 'Direct'
? [idx.algorithm.value]
: idx.algorithm.value;
const unique = tableDef.constraints.some(
c =>
c.data.tag === 'Unique' &&
c.data.value.columns.every(col => columnIds.includes(col))
);
const algorithm = (
{
BTree: 'btree',View on GitHub (pinned to 524b4487d9)
Solutions
- Align versions: upgrade the spacetimedb toolchain/server and the TS bindings to releases that both emit and require accessorName
- If you construct RawTableDef yourself (tests, fixtures), set a non-empty accessorName on every index
- If the host genuinely omits the field on current versions, report it upstream with the def JSON
Example fix
// before
const tableDef: RawTableDef = JSON.parse(fixtureJson); // indexes[].accessorName missing -> throws
// after
for (const idx of tableDef.indexes) {
if (typeof idx.accessorName !== 'string' || idx.accessorName.length === 0) {
idx.accessorName = idx.sourceName!; // backfill before conversion
}
} Defensive patterns
Strategy: validation
Validate before calling
function validateRawTableDefIndexes(tableDef: { indexes: Array<{ sourceName?: string; accessorName?: unknown }>; sourceName: string }): void {
for (const idx of tableDef.indexes) {
if (typeof idx.accessorName !== 'string' || idx.accessorName.length === 0) {
throw new Error(
`tableDef for '${tableDef.sourceName}': index '${idx.sourceName ?? '<unknown>'}' lacks accessorName - host/bindings version mismatch?`
);
}
}
} Prevention
- Keep the spacetimedb host/toolchain and TS bindings on matched versions
- Validate hand-built RawTableDef fixtures with a schema check before conversion
- Fail at startup with a clear version-skew message instead of mid-conversion
When it happens
Trigger: Converting a RawTableDef whose indexes entries lack accessorName - typically a def emitted by an older spacetimedb host/CLI than the TS bindings expect, or a hand-assembled def in tests.
Common situations: Version skew between the SpacetimeDB server/tools that generated the table def and the @clockworklabs bindings that consume it; test fixtures hand-rolling RawTableDef JSON without the full index metadata.
Related errors
- source_name should be provided in V10, accessor_names inside
- Index '${indexLabel}' on table '${tableLabel}' must define a
- Unknown index algorithm {:?}
- cannot serialize refs without a typespace
- cannot deserialize refs without a typespace
AI-assisted analysis of clockworklabs/SpacetimeDB@524b4487d9 (2026-08-16).
Data as JSON: /api/errors/1d46333e787c9c81.
Report an issue: GitHub.