{"record":{"id":"a8abef0b9156d41b","repo":"clockworklabs/SpacetimeDB","slug":"spacetimedbqueryclient-can-only-handle-spacetimedb","errorCode":null,"errorMessage":"SpacetimeDBQueryClient can only handle spacetimedb queries, got: ${prefix}","messagePattern":"SpacetimeDBQueryClient can only handle spacetimedb queries, got: (.+?)","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"crates/bindings-typescript/src/tanstack/SpacetimeDBQueryClient.ts","lineNumber":135,"sourceCode":"          }\n        }\n      });\n  }\n\n  queryFn: QueryFunction<any[], QueryKey> = async ({\n    queryKey,\n  }: {\n    queryKey: QueryKey;\n  }) => {\n    const keyStr = JSON.stringify(queryKey);\n    const [prefix, accessorName, querySql] = queryKey as [\n      string,\n      string,\n      string,\n    ];\n\n    if (prefix !== 'spacetimedb') {\n      throw new Error(\n        `SpacetimeDBQueryClient can only handle spacetimedb queries, got: ${prefix}`\n      );\n    }\n\n    const registered = queryRegistry.get(querySql);\n    const whereExpr = registered?.whereExpr;\n\n    const existingSub = this.subscriptions.get(keyStr);\n    if (existingSub?.applied) {\n      return this.getTableData(existingSub.tableInstance, whereExpr);\n    }\n\n    // queue query if connection not ready yet\n    if (!this.connection) {\n      return new Promise<any[]>(resolve => {\n        const pending = this.pendingQueries.get(keyStr) || [];\n        pending.push({ resolve, querySql, whereExpr });\n        this.pendingQueries.set(keyStr, pending);","sourceCodeStart":117,"sourceCodeEnd":153,"githubUrl":"https://github.com/clockworklabs/SpacetimeDB/blob/6dee26c6efc2856793e12b148a59742964f5d783/crates/bindings-typescript/src/tanstack/SpacetimeDBQueryClient.ts#L117-L153","documentation":"SpacetimeDBQueryClient implements TanStack Query's QueryFunction contract and validates that each incoming queryKey is the triple ['spacetimedb', accessorName, querySql] produced by the spacetimeDBQuery() helper. Any key whose first element is not the literal 'spacetimedb' is rejected, because the client's subscription and cache-hydration logic only understands keys it created (it also looks the SQL string up in an internal queryRegistry filled by spacetimeDBQuery).","triggerScenarios":"Setting SpacetimeDBQueryClient.queryFn as the default queryFn of a QueryClient that also runs non-SpacetimeDB queries; calling queryClient.fetchQuery/prefetchQuery with a hand-built key; overriding or reordering the queryKey returned by spacetimeDBQuery(); spreading the options object but replacing queryKey.","commonSituations":"Hybrid apps mixing REST and SpacetimeDB queries on one QueryClient; refactors that rename or namespace query keys; copying examples that set defaultOptions.queries.queryFn globally.","solutions":["Build query options only with spacetimeDBQuery(tables.x) or spacetimeDBQuery(tables.x.where(...)), never by hand","Do not install this queryFn as the QueryClient's defaultQueryFn if the client also serves other queries — pass it per query","Never override or reorder the queryKey from spacetimeDBQuery(); spread the whole options object into useQuery","If you must construct keys manually, use the exact shape ['spacetimedb', accessorName, sql] and make sure spacetimeDBQuery() ran for that query so it is in the registry"],"exampleFix":"// before\nconst { data } = useQuery({\n  queryKey: ['players', userId], // prefix is not 'spacetimedb'\n  queryFn: stdbQueryClient.queryFn,\n});\n\n// after\nimport { spacetimeDBQuery } from '@clockworklabs/spacetime-db-tanstack';\nconst { data } = useQuery({\n  ...spacetimeDBQuery(tables.player), // queryKey: ['spacetimedb', 'player', sql]\n  queryFn: stdbQueryClient.queryFn,\n});","handlingStrategy":"validation","validationCode":"function isSpacetimeDBKey(key: readonly unknown[]): boolean {\n  return key[0] === 'spacetimedb';\n}\n\n// before wiring the queryFn:\nif (isSpacetimeDBKey(options.queryKey)) {\n  // safe for SpacetimeDBQueryClient.queryFn\n}","typeGuard":"function isSpacetimeDBKey(key: readonly unknown[]): key is readonly ['spacetimedb', string, string] {\n  return (\n    Array.isArray(key) &&\n    key.length === 3 &&\n    key[0] === 'spacetimedb' &&\n    typeof key[1] === 'string' &&\n    typeof key[2] === 'string'\n  );\n}","tryCatchPattern":"// better than catching: never hand-build keys — always spread spacetimeDBQuery(...)","preventionTips":["Only use spacetimeDBQuery() to produce query options","Do not set this queryFn as a QueryClient-wide default alongside REST queries","Code-review any custom queryKey that interacts with this client"],"tags":["tanstack-query","react-query","query-key","typescript"],"backgroundTag":"invalid-query-key","analyzedSha":"6dee26c6efc2856793e12b148a59742964f5d783","analyzedAt":"2026-08-20T06:08:37.179Z","contentChangedAt":"2026-08-20T06:08:37.179Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}