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 React component tree under a `SpacetimeDBProvider` component.
What it means
useTable calls useSpacetimeDB inside a try/catch; when no provider is mounted the context hook throws, and useTable re-throws this 'Could not find SpacetimeDB client' message. The root cause is exactly the missing-provider case: no SpacetimeDBProvider in the component tree above the hook call.
Solutions
- Mount SpacetimeDBProvider above every component that uses useTable
- Use a shared test wrapper component that includes the provider
- Verify the provider is not conditionally skipped on the render that first runs the hook
Example fix
// before
export function Players() {
const [rows] = useTable(playersQuery); // throws: no provider above
...
}
// after
root.render(
<SpacetimeDBProvider connectionBuilder={builder}>
<Players />
</SpacetimeDBProvider>
); Defensive patterns
Strategy: try-catch
Try / catch
// Error boundary (same shape as for useSpacetimeDB) around components using useTable
class TableErrorBoundary extends React.Component<
{ children: React.ReactNode },
{ error?: Error }
> {
state = { error: undefined as Error | undefined };
static getDerivedStateFromError(error: Error) { return { error }; }
render() {
if (this.state.error?.message.includes('SpacetimeDBProvider')) {
return <p>Connect this view to SpacetimeDB first.</p>;
}
return this.props.children;
}
} Prevention
- Ensure SpacetimeDBProvider wraps every component calling useTable
- Share one provider-wrapped wrapper across tests
- Do not mount the provider conditionally after data loads; hooks run on first render
When it happens
Trigger: Using useTable(query, callbacks) in a component rendered outside <SpacetimeDBProvider connectionBuilder={...}>.
Common situations: Same as other missing-provider cases: unwrapped test renders, a new page or modal outside the provider subtree, provider skipped during the first render pass.
Related errors
- useSpacetimeDB must be used within a SpacetimeDBProvider…
- useSpacetimeDB must be used within a component that called…
- useSpacetimeDB must be used within a SpacetimeDBProvider…
- Could not find SpacetimeDB client! Did you forget to call…
- Could not find SpacetimeDB client! Did you forget to add a…
AI-assisted analysis of clockworklabs/SpacetimeDB@6dee26c6ef (2026-08-20).
Data as JSON: /api/errors/03841878d0e42763.
Report an issue: GitHub.
Appendix: source
Thrown at crates/bindings-typescript/src/react/useTable.ts:81
* { onInsert: (row) => console.log('New user:', row) }
* );
* ```
*/
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 accessorName = getQueryAccessorName(query);
const whereExpr = getQueryWhereClause(query);
const [subscribeApplied, setSubscribeApplied] = useState(false);
let connectionState: ConnectionState | undefined;
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 React component tree ' +
'under a `SpacetimeDBProvider` component.'
);
}
const querySql = toSql(query);
const latestTransactionEventId = useRef<string | null>(null);
const lastSnapshotRef = useRef<
[readonly Prettify<UseTableRowType>[], boolean] | null
>(null);
const computeSnapshot = useCallback((): [
readonly Prettify<UseTableRowType>[],
boolean,
] => {
if (!enabled) {View on GitHub (pinned to 6dee26c6ef)