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: TableView on GitHub (pinned to a81a902e9a)
Solutions
- Fetch the datasource schema (run the datasource fetch/sync) so entities are populated before row operations
- Verify the datasource document is complete and linked correctly (check datasource.entities exists before constructing ExternalRequest)
- Re-create or re-link the datasource if its schema is empty in the builder
- 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
- Always run the datasource schema fetch/sync before row operations
- Check datasource.entities is populated when linking datasources programmatically
- Re-create datasources that show no tables in the builder
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
- Source table '${relationship.sourceTable}' not found in data
- Target table '${relationship.targetTable}' not found in data
- TableImportError(errors)
- Please run in a plugin directory - must contain schema.json
- IMAP password is required
AI-assisted analysis of Budibase/budibase@a81a902e9a (2026-08-29).
Data as JSON: /api/errors/8aa5a309bb5603cc.
Report an issue: GitHub.