remix-run/remix · error · DataTableQueryError
' + operation + '() returning is not supported by this datab
Error message
' + operation + '() returning is not supported by this database
What it means
All mutating operations accept a returning option to fetch written rows back, but the adapter's capabilities.returning is false for this database (e.g. MySQL). If returning is requested in that case, a DataTableQueryError is thrown naming the operation, because the library cannot emulate row returning there.
Source
Thrown at packages/data-table/src/lib/database/write-lifecycle.ts:257
context: TableAfterDeleteContext,
): void {
let callback = getTableAfterDelete(table)
if (!callback) {
return
}
let callbackResult = callback(context)
assertSynchronousCallbackResult(context.tableName, 'delete', 'afterDelete', callbackResult)
}
export function assertReturningCapability<row extends Record<string, unknown>>(
capabilities: DatabaseCapabilities,
operation: 'insert' | 'insertMany' | 'update' | 'delete' | 'upsert',
returning: ReturningInput<row> | undefined,
): void {
if (returning && !capabilities.returning) {
throw new DataTableQueryError(operation + '() returning is not supported by this database')
}
}
export function normalizeReturningSelection<row extends Record<string, unknown>>(
returning: ReturningInput<row>,
): ReturningSelection {
if (returning === '*') {
return '*'
}
return [...returning]
}
function validateWriteValues<table extends AnyTable>(
table: table,
values: Partial<TableRow<table>>,
operation: TableWriteOperation,
): Record<string, unknown> {View on GitHub (pinned to 9696913134)
Solutions
- Remove the returning option and re-query rows afterwards with a select where clause
- Use a database/driver that supports RETURNING (Postgres, recent SQLite)
- Branch on database.capabilities.returning if you must support both
Example fix
// before
await table.insert({ values, returning: ['id', 'createdAt'] })
// after
let { id } = await table.insert({ values })
let row = await table.row({ where: { id } }) Defensive patterns
Strategy: type-guard
Validate before calling
let canReturn = database.capabilities.returning
await table.insert({ values, ...(canReturn ? { returning: ['id'] } : {}) }) Type guard
function supportsReturning(database: { capabilities: { returning: boolean } }): boolean {
return database.capabilities.returning === true
} Try / catch
try {
result = await table.insert({ values, returning: ['id', 'createdAt'] })
} catch (error) {
if (error instanceof DataTableQueryError && /returning is not supported/.test(error.message)) {
result = await table.insert({ values })
row = await table.row({ where: { id: result.id } })
} else throw error
} Prevention
- Feature-detect capabilities.returning once at startup
- Write dialect-agnostic code that re-selects instead of using returning
- Document per-environment database support in the project README
When it happens
Trigger: insert/insertMany/update/delete/upsert called with returning: [...] or returning: true while database.capabilities.returning is false.
Common situations: Writing code against Postgres locally then running tests or production on MySQL; upgrading an adapter whose capability detection changed; assuming returning works everywhere because the type accepts it.
Related errors
- create({ returnRow: true }) requires primary key values for
- create({ returnRow: true }) failed to return an inserted row
- create({ returnRow: true }) failed to load inserted row
- createMany({ returnRows: true }) is not supported by this da
- Database does not support upsert
AI-assisted analysis of remix-run/remix@9696913134 (2026-08-27).
Data as JSON: /api/errors/41a311fcae077acf.
Report an issue: GitHub.