clockworklabs/SpacetimeDB · error · Error

Cannot extract table name from query

Error message

Cannot extract table name from query

What it means

The uninstaller refuses to remove the version the bin dir's current symlink points to, because that is the CLI installation you are effectively running. It reads current_version() (a read failure is only warned about, not fatal) and compares it with the requested version before touching the directory.

Solutions

  1. Switch to another installed version first: spacetime update install <other-version> --use, then uninstall the old one.
  2. If it is the only installed version, install a newer one with --use and uninstall this one afterwards.
  3. Verify with spacetime update list that the current marker moved before uninstalling.

Example fix

# before
spacetime update uninstall 1.7.1   # 1.7.1 is current -> refused

# after
spacetime update install 1.7.2 --use
spacetime update uninstall 1.7.1
Defensive patterns

Strategy: validation

Validate before calling

current="$(basename "$(readlink "$BIN_DIR/current")")"
[[ "$VERSION" != "$current" ]] \
  || { echo "switch away from $VERSION before uninstalling it"; exit 1; }

Prevention

When it happens

Trigger: spacetime update uninstall <v> where <v> equals the target of the current symlink (e.g. you installed 1.7.1 with --use, then try to uninstall 1.7.1).

Common situations: Cleaning up old versions without remembering which one is active; several versions piled up after repeated install --use switches.

Related errors


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

Appendix: source

Thrown at crates/bindings-typescript/src/lib/query.ts:1046

export function toComparableValue(value: any): any {
  // Handle `ConnectionId` and `Identity`.
  if (isHexSerializableLike(value)) {
    return value.toHexString();
  }
  if (isTimestampLike(value)) {
    return value.__timestamp_micros_since_unix_epoch__;
  }
  return value;
}

/**
 * Extract the table name from a query builder expression.
 */
export function getQueryTableName(query: any): string {
  if (query.table) return query.table.name; // FromBuilder
  if (query.name) return query.name; // TableRefImpl
  if (query.sourceQuery) return query.sourceQuery.table.name; // SemijoinImpl (source table)
  throw new Error('Cannot extract table name from query');
}

/**
 * Extract the accessor name from a query builder expression.
 */
export function getQueryAccessorName(query: any): string {
  if (query.table) return query.table.accessorName; // FromBuilder
  if (query.accessorName) return query.accessorName; // TableRefImpl
  if (query.sourceQuery) return query.sourceQuery.table.accessorName; // SemijoinImpl
  throw new Error('Cannot extract accessor name from query');
}

/**
 * Extract the BooleanExpr from a query builder, if any.
 */
export function getQueryWhereClause(query: any): BooleanExpr<any> | undefined {
  if (query.whereClause) return query.whereClause; // FromBuilder
  return undefined; // TableRefImpl has no where clause

View on GitHub (pinned to 6dee26c6ef)