clockworklabs/SpacetimeDB · error · TypeError

wrong number of elements

Error message

wrong number of elements

What it means

For a multi-column unique index (including composite unique constraints), find() serializes its argument as a point key: you must pass exactly one value per indexed column, in index order. Passing a scalar, too few, or too many elements throws TypeError('wrong number of elements') before any datastore call is made.

Source

Thrown at crates/bindings-typescript/src/server/runtime.ts:1281

          BINARY_WRITER.reset(buf);
          serializeRow(BINARY_WRITER, row);
          sys.datastore_update_bsatn(
            table_id,
            index_id,
            buf.buffer,
            BINARY_WRITER.offset
          );
          integrateGeneratedColumns?.(row, buf.view);
          return row;
        };
      }
      index = base as UniqueIndex<any, any>;
    } else if (isUnique) {
      // numColumns != 1, unique index
      const base = {
        find: (colVal: IndexVal<any, any>): RowType<any> | null => {
          if (colVal.length !== numColumns) {
            throw new TypeError('wrong number of elements');
          }
          const buf = LEAF_BUF;
          const point_len = serializePoint(buf, colVal);
          const iter_id = sys.datastore_index_scan_point_bsatn(
            index_id,
            buf.buffer,
            point_len
          );
          return tableIterateOne(iter_id, deserializeRow);
        },
        delete: (colVal: IndexVal<any, any>): boolean => {
          if (colVal.length !== numColumns)
            throw new TypeError('wrong number of elements');

          const buf = LEAF_BUF;
          const point_len = serializePoint(buf, colVal);
          const num = sys.datastore_delete_by_index_scan_point_bsatn(
            index_id,

View on GitHub (pinned to 524b4487d9)

Solutions

  1. Pass an array with exactly one value per indexed column, in index order: find([region, id])
  2. Regenerate/refresh type information after changing index definitions so arity errors surface at compile time
  3. Centralize each index lookup in one helper so the correct arity is written in a single place

Example fix

// before (unique index on [region, id])
const user = ctx.db.users.byRegionId.find(id); // scalar against 2-column index

// after
const user = ctx.db.users.byRegionId.find([region, id]);
Defensive patterns

Strategy: type-guard

Validate before calling

// before calling find on a composite unique index covering N columns:
function assertIndexKey(colVal: unknown[], numColumns: number): void {
  if (!Array.isArray(colVal) || colVal.length !== numColumns) {
    throw new Error(`expected ${numColumns} key values, got ${Array.isArray(colVal) ? colVal.length : typeof colVal}`);
  }
}

Type guard

const hasIndexArity = (v: unknown, n: number): v is unknown[] =>
  Array.isArray(v) && v.length === n;

// usage:
if (hasIndexArity(key, 2)) ctx.db.users.byRegionId.find(key as [typeof region, typeof id]);

Prevention

When it happens

Trigger: Calling find(scalarValue) against a 2-column unique index; find([a]) or find([a, b, c]) where the index covers exactly 2 columns; call sites not updated after the index definition changed arity.

Common situations: Index changed from single-column to composite (or vice versa) without updating queries; copy-paste from a table with a single-column index; stale generated bindings after a schema edit.

Related errors


AI-assisted analysis of clockworklabs/SpacetimeDB@524b4487d9 (2026-08-16). Data as JSON: /api/errors/6dd124c5fbafea93. Report an issue: GitHub.