Skip to content

TypeScript codegen: missing accessor on index definitions causes runtime TypeError #4599

@weslien

Description

@weslien

Bug Description

spacetime generate --lang typescript produces index definitions with only name, but the SDK's table() function reads indexOpts.accessor to set the TypeScript accessor name on conn.db.<table>. Since accessor is missing from generated code, all non-implicit index lookups are undefined at runtime.

Steps to Reproduce

  1. Define a table with explicit indexes in a TypeScript server module:
const myTable = table({
  name: 'my_table',
  public: true,
  indexes: [
    { name: 'my_table_owner_id', accessor: 'my_table_owner_id', algorithm: 'btree', columns: ['owner_id'] },
  ],
}, {
  id: t.u64().primaryKey().autoInc(),
  owner_id: t.identity(),
});
  1. Run spacetime generate --lang typescript to produce client bindings.

  2. The generated index.ts produces index entries like:

// Generated output — missing `accessor`
{ name: 'my_table_owner_id', algorithm: 'btree', columns: ['ownerId'] }
  1. At runtime, conn.db.myTable.my_table_owner_id is undefined.

  2. Calling .filter() on it throws:

TypeError: Cannot read properties of undefined (reading 'filter')

Expected Behavior

Generated index definitions should include the accessor property:

// Expected output
{ name: 'my_table_owner_id', accessor: 'my_table_owner_id', algorithm: 'btree', columns: ['ownerId'] }

Root Cause

In node_modules/spacetimedb/src/lib/table.ts (line ~430), explicit indexes read indexOpts.accessor:

indexes.push({
  sourceName: undefined,
  accessorName: indexOpts.accessor,  // <-- reads `.accessor`, not `.name`
  algorithm,
  canonicalName: indexOpts.name,
});

The codegen writes name but the SDK reads accessor. Without accessor, accessorName is undefined and the index is not accessible on the conn.db object.

Workaround

Manually add accessor properties to all index definitions in the generated index.ts:

// Before (broken)
{ name: 'my_table_owner_id', algorithm: 'btree', columns: ['ownerId'] }

// After (works)
{ name: 'my_table_owner_id', accessor: 'my_table_owner_id', algorithm: 'btree', columns: ['ownerId'] }

This workaround is fragile — it gets overwritten on each spacetime generate.

Environment

  • SpacetimeDB CLI: 2.0.3
  • SpacetimeDB TypeScript SDK: 2.0.2
  • Codegen version string in generated file: 2.0.2 (commit bc4fcec6f33f607fb46f61ae66c479eecf5a6e74)
  • Platform: macOS (Darwin 25.2.0)
  • Node.js: v22

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions