clockworklabs/SpacetimeDB · error · Error

Could not find SpacetimeDB client! Did you forget to add a…

Error message

Could not find SpacetimeDB client! Did you forget to add a `SpacetimeDBProvider`? `useTable` must be used in the SolidJS component tree under a `SpacetimeDBProvider` component.

What it means

useTable in the Solid bindings calls useSpacetimeDB() inside a try/catch; when the context lookup fails because there is no SpacetimeDBProvider above, the original error is discarded and this dedicated message is thrown instead. The subscription machinery cannot even start because there is no connection to subscribe with, so the hook fails immediately at call time, before the enabled() gate is consulted.

Solutions

  1. Add <SpacetimeDBProvider connectionBuilder={builder}> above the component calling useTable
  2. Confirm you used the Solid bindings' own provider, not the React or Vue one
  3. In tests, render the component inside the provider before asserting rows
  4. Check that the useTable import comes from the solid entry point and that the provider wraps the whole subtree

Example fix

// before
export default function App() {
  const [players] = useTable(tables.player); // throws: no provider above
  return <For each={players}>{(p) => <div>{p.name}</div>}</For>;
}

// after
import { SpacetimeDBProvider } from '@clockworklabs/spacetime-db-solid';

export default function App() {
  return (
    <SpacetimeDBProvider connectionBuilder={builder}>
      <Players />
    </SpacetimeDBProvider>
  );
}
Defensive patterns

Strategy: try-catch

Validate before calling

import { useContext } from 'solid-js';
import { SpacetimeDBContext } from './solid/useSpacetimeDB';

// gate hook usage on provider presence
const canUseTables = () => useContext(SpacetimeDBContext) !== undefined;

Try / catch

// useTable throws during render; wrap consumers in Solid's ErrorBoundary
<ErrorBoundary fallback={(err) => <div>{String(err)}</div>}>
  <TableComponent />
</ErrorBoundary>

Prevention

When it happens

Trigger: Calling useTable(tables.x) or useTable(query, { enabled }) from the Solid bindings inside a component that lacks a <SpacetimeDBProvider connectionBuilder={...}> ancestor. Even conditionally enabled queries throw, because the provider check runs before the enabled() check.

Common situations: Provider added to a subset of routes while a shared component uses useTable; tests rendering the table component in isolation; porting from React where the provider API differs; provider placed after (below) the consumer in the tree.

Related errors


AI-assisted analysis of clockworklabs/SpacetimeDB@6dee26c6ef (2026-08-20). Data as JSON: /api/errors/b33c7b2eb89a18ab. Report an issue: GitHub.

Appendix: source

Thrown at crates/bindings-typescript/src/solid/useTable.ts:76

 * );
 * ```
 */
export function useTable<TableDef extends UntypedTableDef>(
  query: () => Query<TableDef>,
  callbacks?: UseTableCallbacks<Prettify<RowType<TableDef>>>
): [readonly Prettify<RowType<TableDef>>[], () => boolean] {
  type UseTableRowType = RowType<TableDef>;
  const enabled = callbacks?.enabled ?? (() => true);
  const q = createMemo(query);
  const accessorName = createMemo(() => getQueryAccessorName(q()));
  const whereExpr = createMemo(() => getQueryWhereClause(q()));
  const querySql = createMemo(() => toSql(q()));

  let connectionState: import('./connection_state').ConnectionState;
  try {
    connectionState = useSpacetimeDB();
  } catch {
    throw new Error(
      'Could not find SpacetimeDB client! Did you forget to add a ' +
        '`SpacetimeDBProvider`? `useTable` must be used in the SolidJS component tree ' +
        'under a `SpacetimeDBProvider` component.'
    );
  }

  const [rows, setRows] = createStore<readonly Prettify<UseTableRowType>[]>([]);

  let latestTransactionEventId: string | null = null;

  const computeSnapshot = (): readonly Prettify<UseTableRowType>[] => {
    if (!enabled()) {
      return [];
    }

    const connection = connectionState.getConnection();
    if (!connection) {
      return [];

View on GitHub (pinned to 6dee26c6ef)