{"record":{"id":"bd236bd2975d31bc","repo":"clockworklabs/SpacetimeDB","slug":"tableid-return-id-does-not-exist","errorCode":null,"errorMessage":"TableId `{return_id}` does not exist","messagePattern":"TableId `(.+?)` does not exist","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/query/src/lib.rs","lineNumber":42,"sourceCode":"const MAX_SQL_LENGTH: usize = 50_000;\n\npub fn compile_subscription(\n    sql: &str,\n    tx: &impl SchemaView,\n    auth: &AuthCtx,\n) -> Result<(Vec<ProjectPlan>, TableId, TableName, bool)> {\n    if sql.len() > MAX_SQL_LENGTH {\n        bail!(\"SQL query exceeds maximum allowed length: \\\"{sql:.120}...\\\"\")\n    }\n\n    let (plan, mut has_param) = parse_and_type_sub(sql, tx, auth)?;\n\n    let Some(return_id) = plan.return_table_id() else {\n        bail!(\"Failed to determine TableId for query\")\n    };\n\n    let Some(return_name) = tx.schema_for_table(return_id).map(|schema| schema.table_name.clone()) else {\n        bail!(\"TableId `{return_id}` does not exist\")\n    };\n\n    // Resolve any RLS filters\n    let plan_fragments = resolve_views_for_sub(tx, plan, auth, &mut has_param)?\n        .into_iter()\n        .map(compile_select)\n        .collect::<Vec<_>>();\n\n    // Does this subscription read from a client-specific view?\n    // If so, it is as if the view is parameterized by `:sender`.\n    // We must know this in order to generate the correct query hash.\n    let reads_view = plan_fragments.iter().any(|plan| plan.reads_from_view(false));\n\n    Ok((plan_fragments, return_id, return_name, has_param || reads_view))\n}\n\n/// A utility for parsing and type checking a sql statement\npub fn compile_sql_stmt(sql: &str, tx: &impl SchemaView, auth: &AuthCtx) -> Result<Statement> {","sourceCodeStart":24,"sourceCodeEnd":60,"githubUrl":"https://github.com/clockworklabs/SpacetimeDB/blob/6dee26c6efc2856793e12b148a59742964f5d783/crates/query/src/lib.rs#L24-L60","documentation":"After the subscription's return TableId is resolved, compile_subscription looks up the schema for that id via tx.schema_for_table(return_id). A None result means no table with that id exists in the database schema, so the query is rejected.","triggerScenarios":"Subscribing to a table that was dropped or renamed by a migration, or reusing a cached table reference from an old schema version after the module was republished.","commonSituations":"Clients holding stale subscriptions or generated bindings across a publish that changed table names; racing a subscribe against an in-flight schema migration.","solutions":["Re-fetch the schema on the client (regenerate bindings / re-describe the database) and re-subscribe using the new table name.","Verify the table exists: spacetetime describe <db> or spacetime sql <db> \"SELECT * FROM ...\" against the target table.","Re-subscribe only after the publish/migration has fully completed."],"exampleFix":"# before: stale table name from old bindings\nsubscription = await db.subscription \"SELECT * FROM old_table\"\n\n# after: regenerate bindings, use current table name\nspacetime generate --lang typescript --out-dir ./module_bindings\nsubscription = await db.subscription \"SELECT * FROM renamed_table\"","handlingStrategy":"retry","validationCode":"# before (re)subscribing after a publish, confirm the table exists:\nspacetime describe my-db\n# or from the client: fetch the database schema and check the table name is present","typeGuard":null,"tryCatchPattern":"try {\n  await db.subscription.build([`SELECT * FROM ${table}`]).subscribe();\n} catch (e: any) {\n  if (String(e.message).includes(\"does not exist\")) {\n    await db.refreshSchema(); // or regenerate bindings, then retry once\n    await db.subscription.build([`SELECT * FROM ${newTable}`]).subscribe();\n  }\n}","preventionTips":["Regenerate client bindings immediately after every publish that changes tables.","Resubscribe after migrations complete, not concurrently with them.","Handle subscription errors by re-fetching schema and rebuilding queries."],"tags":["subscription","table-not-found","schema","migration"],"backgroundTag":"table-not-found","analyzedSha":"6dee26c6efc2856793e12b148a59742964f5d783","analyzedAt":"2026-08-20T06:08:37.179Z","contentChangedAt":"2026-08-20T06:08:37.179Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}