Budibase/budibase · error · Error

Cannot generate query tool bindings without a query ID

Error message

Cannot generate query tool bindings without a query ID

What it means

getBindings generates AI tool bindings for a query, which requires a persisted document ID. If query._id is missing (unsaved or in-memory query object), it cannot build stable binding references and throws a plain Error before computing the tool type (REST_QUERY vs DATASOURCE_QUERY).

Source

Thrown at packages/server/src/sdk/workspace/ai/agents/queryToolReferences.ts:127

    return {
      ...operation,
      promptInstructions,
      enabledTools,
    }
  })

  return changed ? { ...agent, operations } : undefined
}

const getBindings = ({
  datasource,
  query,
}: {
  datasource: Datasource
  query: Query
}) => {
  if (!query._id) {
    throw new Error("Cannot generate query tool bindings without a query ID")
  }
  const sourceType: QueryToolType =
    datasource.source === SourceName.REST
      ? ToolType.REST_QUERY
      : ToolType.DATASOURCE_QUERY
  return getQueryToolBindings({
    sourceType,
    sourceLabel:
      datasource.name ||
      (sourceType === ToolType.REST_QUERY ? "API" : "Datasource"),
    queryName: query.name,
    queryId: query._id,
  })
}

export const migrateQueryToolReferences = async (
  migrations: QueryToolReferenceMigration | QueryToolReferenceMigration[]
): Promise<void> => {

View on GitHub (pinned to a81a902e9a)

Solutions

  1. Persist the query first (save/query API) so it has an _id, then call getBindings.
  2. Validate query._id in the calling code and skip or defer binding generation for unsaved queries.
  3. If constructing queries in tests/scripts, set a realistic _id before invoking getBindings.

Example fix

// before
getBindings({ datasource, query: draftQuery }) // throws
// after
const saved = await api.saveQuery(draftQuery)
if (!saved._id) throw new Error("Query must be saved")
getBindings({ datasource, query: saved })
Defensive patterns

Strategy: type-guard

Validate before calling

if (!query._id) {
  throw new Error("Save the query before generating tool bindings")
}
getBindings({ datasource, query })

Type guard

const isPersistedQuery = (query: Query): query is Query & { _id: string } =>
  typeof query._id === "string" && query._id.length > 0

Try / catch

try {
  const bindings = getBindings({ datasource, query })
} catch (err) {
  if ((err as Error).message.includes("without a query ID")) {
    // defer binding generation until the query is saved
  }
}

Prevention

When it happens

Trigger: Calling getBindings({ datasource, query }) with a Query object that has not been saved to the database (_id undefined), e.g. building bindings for a newly drafted query before persisting it.

Common situations: Syncing query tool bindings during datasource import/edit flows before the query save completes; constructing a Query object manually in code or tests without an _id.

Related errors


AI-assisted analysis of Budibase/budibase@a81a902e9a (2026-08-29). Data as JSON: /api/errors/be027550cf2e0e68. Report an issue: GitHub.