{"record":{"id":"41a311fcae077acf","repo":"remix-run/remix","slug":"operation-returning-is-not-supported-by","errorCode":null,"errorMessage":"' + operation + '() returning is not supported by this database","messagePattern":"' \\+ operation \\+ '\\(\\) returning is not supported by this database","errorType":"exception","errorClass":"DataTableQueryError","httpStatus":null,"severity":"error","filePath":"packages/data-table/src/lib/database/write-lifecycle.ts","lineNumber":257,"sourceCode":"  context: TableAfterDeleteContext,\n): void {\n  let callback = getTableAfterDelete(table)\n\n  if (!callback) {\n    return\n  }\n\n  let callbackResult = callback(context)\n  assertSynchronousCallbackResult(context.tableName, 'delete', 'afterDelete', callbackResult)\n}\n\nexport function assertReturningCapability<row extends Record<string, unknown>>(\n  capabilities: DatabaseCapabilities,\n  operation: 'insert' | 'insertMany' | 'update' | 'delete' | 'upsert',\n  returning: ReturningInput<row> | undefined,\n): void {\n  if (returning && !capabilities.returning) {\n    throw new DataTableQueryError(operation + '() returning is not supported by this database')\n  }\n}\n\nexport function normalizeReturningSelection<row extends Record<string, unknown>>(\n  returning: ReturningInput<row>,\n): ReturningSelection {\n  if (returning === '*') {\n    return '*'\n  }\n\n  return [...returning]\n}\n\nfunction validateWriteValues<table extends AnyTable>(\n  table: table,\n  values: Partial<TableRow<table>>,\n  operation: TableWriteOperation,\n): Record<string, unknown> {","sourceCodeStart":239,"sourceCodeEnd":275,"githubUrl":"https://github.com/remix-run/remix/blob/9696913134be3a4423513d2775f7b31d6917c049/packages/data-table/src/lib/database/write-lifecycle.ts#L239-L275","documentation":"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.","triggerScenarios":"insert/insertMany/update/delete/upsert called with returning: [...] or returning: true while database.capabilities.returning is false.","commonSituations":"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.","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"],"exampleFix":"// before\nawait table.insert({ values, returning: ['id', 'createdAt'] })\n\n// after\nlet { id } = await table.insert({ values })\nlet row = await table.row({ where: { id } })","handlingStrategy":"type-guard","validationCode":"let canReturn = database.capabilities.returning\nawait table.insert({ values, ...(canReturn ? { returning: ['id'] } : {}) })","typeGuard":"function supportsReturning(database: { capabilities: { returning: boolean } }): boolean {\n  return database.capabilities.returning === true\n}","tryCatchPattern":"try {\n  result = await table.insert({ values, returning: ['id', 'createdAt'] })\n} catch (error) {\n  if (error instanceof DataTableQueryError && /returning is not supported/.test(error.message)) {\n    result = await table.insert({ values })\n    row = await table.row({ where: { id: result.id } })\n  } else throw error\n}","preventionTips":["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"],"tags":["data-table","returning","database-capabilities"],"backgroundTag":"unsupported-database-feature","analyzedSha":"9696913134be3a4423513d2775f7b31d6917c049","analyzedAt":"2026-08-27T19:55:01.024Z","schemaVersion":2},"datasetVersion":"2026-08-28T00:17:15.603Z"}