clockworklabs/SpacetimeDB · error · Error

Cannot extract accessor name from query

Error message

Cannot extract accessor name from query

What it means

When spacetimedb-update's CLI proxy runs from a cargo target/ directory (a dev checkout), it proxies to the spacetimedb-cli binary cargo should have built into the same artifact directory (target/<profile>/spacetimedb-cli), instead of the installed current version. If that binary is absent, it bails with explicit build instructions.

Solutions

  1. Build the CLI into the same profile: cargo build -p spacetimedb-cli (add --release if you run the release updater).
  2. Or run the installed updater outside target/ so it resolves the CLI via the current version directory instead.
  3. If you meant to run the repo CLI, prefer cargo run -p spacetimedb-cli -- <args>.

Example fix

# before
$ ./target/debug/spacetimedb-update --version
error: ... spacetimedb-cli binary doesn't exist ...

# after
$ cargo build -p spacetimedb-cli
$ ./target/debug/spacetimedb-update --version
Defensive patterns

Strategy: validation

Validate before calling

# Ensure the CLI exists in the same profile as the updater you run:
PROFILE=debug   # or release
test -x "target/$PROFILE/spacetimedb-cli" \
  || cargo build -p spacetimedb-cli $([ "$PROFILE" = release ] && echo --release)

Prevention

When it happens

Trigger: Executing target/debug/spacetimedb-update (or target/release/...) in the SpacetimeDB repo when spacetimedb-cli has not been built into the same profile directory — e.g. after only building the update crate, or after cargo clean.

Common situations: cargo build -p spacetimedb-update only; cargo clean between builds; copying the updater binary out of a partial build tree and running it from target/.

Related errors


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

Appendix: source

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

/**
 * 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
}

// TODO: Fix this.
function _createIndexedRowExpr<TableDef extends TypedTableDef>(
  tableDef: TableDef,
  cols: RowExpr<TableDef>
): IndexedRowExpr<TableDef> {
  const indexed = new Set<ColumnNames<TableDef>>();
  for (const idx of tableDef.indexes) {
    if ('columns' in idx) {

View on GitHub (pinned to 6dee26c6ef)