Budibase/budibase · error

Datasource does not have entities

Error message

Datasource does not have entities

What it means

ExternalRequest wraps all row operations against non-internal (SQL/REST/etc.) datasources. Its private tables getter throws this plain Error when the linked datasource document has no entities — i.e. the datasource was fetched/linked but never had its schema (tables) populated or fetched.

Source

Thrown at packages/server/src/api/controllers/row/ExternalRequest.ts:186

    operation: T,
    source: Table | ViewV2,
    opts: { datasource?: Datasource } = {}
  ) {
    if (!opts.datasource) {
      if (sdk.views.isView(source)) {
        const table = await sdk.views.getTable(source.id)
        opts.datasource = await sdk.datasources.get(table.sourceId)
      } else {
        opts.datasource = await sdk.datasources.get(source.sourceId)
      }
    }

    return new ExternalRequest(operation, source, opts.datasource)
  }

  private get tables(): { [key: string]: Table } {
    if (!this.datasource.entities) {
      throw new Error("Datasource does not have entities")
    }
    return this.datasource.entities
  }

  private constructor(
    operation: T,
    source: Table | ViewV2,
    datasource: Datasource
  ) {
    this.operation = operation
    this.source = source
    this.datasource = datasource
  }

  private prepareFilters(
    id: string | undefined | string[],
    filters: SearchFilters,
    table: Table

View on GitHub (pinned to a81a902e9a)

Solutions

  1. Fetch the datasource schema (run the datasource fetch/sync) so entities are populated before row operations
  2. Verify the datasource document is complete and linked correctly (check datasource.entities exists before constructing ExternalRequest)
  3. Re-create or re-link the datasource if its schema is empty in the builder
  4. Retry the row operation after the datasource schema sync completes

Example fix

// before
const req = new ExternalRequest(op, source, { datasource }) // entities undefined
// after
const fetched = await datasourceFetchSchema(datasource)
if (!fetched.entities) throw new Error("Datasource schema must be fetched first")
const req = new ExternalRequest(op, source, { datasource: fetched })
Defensive patterns

Strategy: type-guard

Validate before calling

if (!datasource?.entities || Object.keys(datasource.entities).length === 0) {
  throw new Error("Datasource schema must be fetched before row operations")
}

Type guard

const hasEntities = (
  d: unknown
): d is { entities: Record<string, Table> } =>
  typeof d === "object" && d !== null &&
  "entities" in d && typeof (d as { entities: unknown }).entities === "object" &&
  (d as { entities: unknown }).entities !== null

Try / catch

try {
  return new ExternalRequest(operation, source, { datasource })
} catch (e) {
  if (/does not have entities/.test(e?.message)) {
    // trigger datasource schema fetch then retry
  } else throw e
}

Prevention

When it happens

Trigger: Performing row operations via ExternalRequest when opts.datasource.entities is undefined/null — typically a datasource document loaded without running its schema fetch, or a datasource that failed to return entities.

Common situations: Datasources created but never 'fetched' in the builder so entities were never saved; datasource linkage pointing at an empty/degenerate document; custom code paths constructing ExternalRequest with a partial datasource object.

Related errors


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