remix-run/remix · error · DataTableQueryError
create({ returnRow: true }) failed to return an inserted row
Error message
create({ returnRow: true }) failed to return an inserted row What it means
When create() is called with returnRow: true and the database supports RETURNING, it executes the insert with returning: '*' and expects a row back. If the driver returns no row (result.row is null/undefined), this error is thrown, indicating the insert succeeded as a statement but the driver/compiler failed to return the inserted data — a driver contract violation rather than a caller mistake.
Source
Thrown at packages/data-table/src/lib/database.ts:580
options?: CreateResultOptions | CreateRowOptions<table, relations>,
): Promise<WriteResult | TableRowWith<table, LoadedRelationMap<relations>>> {
let touch = options?.touch
let query: QueryForTable<table> = this.query(asQueryTableInput(table))
if (options?.returnRow !== true) {
let result = await query.insert(values, { touch })
return toWriteResult(result)
}
if (this.capabilities.returning) {
let result = (await query.insert(values, {
returning: '*',
touch,
})) as { row: TableRow<table> | null }
let row = result.row
if (!row) {
throw new DataTableQueryError(
'create({ returnRow: true }) failed to return an inserted row',
)
}
if (!options.with) {
return row as TableRowWith<table, LoadedRelationMap<relations>>
}
let where = getPrimaryKeyWhereFromRow(table, row)
let loaded = await this.findOne(table, {
where,
with: options.with,
})
if (!loaded) {
throw new DataTableQueryError('create({ returnRow: true }) failed to load inserted row')
}
View on GitHub (pinned to 9696913134)
Solutions
- If you maintain the driver, ensure inserts with returning: '*' resolve with { row } populated from the RETURNING result.
- If using a built-in driver, update data-table and driver packages to matching versions — this indicates a driver bug.
- As a workaround, drop returnRow and re-fetch the row yourself via findOne using the primary key.
Example fix
// before
let row = await db.create(users, values, { returnRow: true })
// after
let result = await db.create(users, values)
let row = await db.findOne(users, eq(users.id, result.primaryKey)) Defensive patterns
Strategy: fallback
Validate before calling
if (db.capabilities.returning) {
row = await db.create(table, values, { returnRow: true })
} else {
await db.create(table, values)
row = await db.findOne(table, where)
} Try / catch
try {
return await db.create(t, v, { returnRow: true })
} catch (error) {
if (error instanceof DataTableQueryError && /failed to return/.test(error.message)) {
return await db.findOne(t, where) // manual fallback
}
throw error
} Prevention
- Check db.capabilities.returning before requesting rows back.
- Report driver bugs upstream with the failing operation.
When it happens
Trigger: db.create(table, values, { returnRow: true }) on a database advertising capabilities.returning where the RETURNING clause is dropped or the driver mis-parses the returned row; custom drivers that resolve inserts without echoing rows.
Common situations: Writing/testing a custom driver that forgets to map RETURNING results; SQLite wrappers where lastInsertRowid is used but the row fetch fails; version skew between driver and core.
Related errors
- create({ returnRow: true }) failed to load inserted row
- MySQL database + method + () requires config-based construc
- createMany({ returnRows: true }) is not supported by this da
- Database execution failed
- create({ returnRow: true }) requires primary key values for
AI-assisted analysis of remix-run/remix@9696913134 (2026-08-27).
Data as JSON: /api/errors/fd65e5888a1706d5.
Report an issue: GitHub.