Budibase/budibase · error · HTTPError

err.message (rethrown as HTTPError)

Error message

err.message (rethrown as HTTPError)

What it means

The external table create/save path wraps the underlying save() call: any Error thrown during datasource table persistence (SQL connector failure, schema error) is rethrown as an HTTPError with status 400 and the original message. This normalizes internal errors into client-facing 400 responses.

Source

Thrown at packages/server/src/sdk/workspace/tables/external/index.ts:116

  if (table.sourceId) {
    return table.sourceId
  }
  if (!table._id) {
    throw new Error("No table ID supplied")
  }
  return breakExternalTableId(table._id).datasourceId
}

export async function create(table: WithoutDocMetadata<Table>) {
  const datasourceId = getDatasourceId(table)

  const tableToCreate = { ...table, created: true }
  try {
    const result = await save(datasourceId!, tableToCreate)
    return result.table
  } catch (err: any) {
    if (err instanceof Error) {
      throw new HTTPError(err.message, 400)
    } else {
      throw new HTTPError(err?.message || err, err.status || 500)
    }
  }
}

export async function save(
  datasourceId: string,
  update: Table,
  opts?: { tableId?: string; renaming?: RenameColumn }
) {
  let tableToSave: TableRequest = {
    ...update,
    type: "table",
    _id: buildExternalTableId(datasourceId, update.name),
    sourceId: datasourceId,
  }

View on GitHub (pinned to a81a902e9a)

Solutions

  1. Read the embedded err.message to identify the underlying connector/SQL failure
  2. Verify the external database connection and credentials are valid
  3. Validate table schema (column names, types) before calling create
  4. Fix the root cause in the connected datasource (permissions, reserved names, constraints)

Example fix

// before
await tables.external.create(badTable) // HTTPError 400: SQL error...
// after
try {
  await tables.external.create(badTable)
} catch (err) {
  // err.status === 400, err.message holds the connector error
  console.error("Table creation failed:", err.message)
}
Defensive patterns

Strategy: try-catch

Validate before calling

if (!table.sourceId && !table._id) return rejectEarly()
if (!Object.keys(table.schema || {}).length) return rejectEarly()

Type guard

function isHTTPError(err: unknown): err is HTTPError {
  return err instanceof HTTPError
}

Try / catch

try {
  await tables.external.create(table)
} catch (err) {
  if (err instanceof HTTPError && err.status === 400) {
    console.error("External table save failed:", err.message)
  } else {
    throw err
  }
}

Prevention

When it happens

Trigger: Any Error thrown inside save(datasourceId, tableToCreate) during external table creation — SQL execution failures, connector errors, relationship generation errors — surfaces as HTTPError(err.message, 400).

Common situations: SQL syntax/permission errors in the underlying database when creating tables; invalid column definitions sent to the connector; relationship constraints failing at the database level.

Related errors


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