{"record":{"id":"e84c7c07ee4b92f8","repo":"n8n-io/n8n","slug":"output-or-returning-clause-only-supported-by-micro","errorCode":null,"errorMessage":"OUTPUT or RETURNING clause only supported by Microsoft SQL Server or PostgreSQL or MariaDB databases.","messagePattern":"OUTPUT or RETURNING clause only supported by Microsoft SQL Server or PostgreSQL or MariaDB databases\\.","errorType":"exception","errorClass":"ReturningStatementNotSupportedError","httpStatus":null,"severity":"error","filePath":"packages/@n8n/typeorm/src/query-builder/DeleteQueryBuilder.ts","lineNumber":237,"sourceCode":"\n\t/**\n\t * Optional returning/output clause.\n\t * Returning is a SQL string containing returning statement.\n\t */\n\treturning(returning: string): this;\n\n\t/**\n\t * Optional returning/output clause.\n\t */\n\treturning(returning: string | string[]): this;\n\n\t/**\n\t * Optional returning/output clause.\n\t */\n\treturning(returning: string | string[]): this {\n\t\t// not all databases support returning/output cause\n\t\tif (!this.connection.driver.isReturningSqlSupported('delete')) {\n\t\t\tthrow new ReturningStatementNotSupportedError();\n\t\t}\n\n\t\tthis.expressionMap.returning = returning;\n\t\treturn this;\n\t}\n\n\t// -------------------------------------------------------------------------\n\t// Protected Methods\n\t// -------------------------------------------------------------------------\n\n\t/**\n\t * Creates DELETE express used to perform query.\n\t */\n\tprotected createDeleteExpression() {\n\t\tconst tableName = this.getTableName(this.getMainTableName());\n\t\tconst whereExpression = this.createWhereExpression();\n\t\tconst returningExpression = this.createReturningExpression('delete');\n","sourceCodeStart":219,"sourceCodeEnd":255,"githubUrl":"https://github.com/n8n-io/n8n/blob/5ac6606e81f67bb9534255570cd4e86fd8101eee/packages/@n8n/typeorm/src/query-builder/DeleteQueryBuilder.ts#L219-L255","documentation":"DeleteQueryBuilder.returning() calls connection.driver.isReturningSqlSupported('delete') and throws ReturningStatementNotSupportedError when it returns false. RETURNING (Postgres) / OUTPUT (SQL Server) lets a DELETE return deleted columns, but drivers like older MySQL, Oracle, SAP HANA, and some SQLite configurations reject it. The guard runs at build configuration time, before any SQL is sent.","triggerScenarios":"Calling .returning(['id']).delete().from(Entity).execute() (or delete().returning(...)) against a driver whose isReturningSqlSupported('delete') is false. Determined by the driver class: MssqlDriver and Postgres/AuroraPostgres return true; better-sqlite3 with 'enable-wal' may; MongoDriver, OracleDriver, MysqlDriver (pre-8 for some paths), SapDriver do not.","commonSituations":"Writing portable code against SQLite/MySQL in dev and Postgres in CI. Copying a Postgres RETURNING pattern into a feature that must run on MySQL/MariaDB. Forgetting that MongoDB driver is fundamentally non-relational.","solutions":["Guard the .returning() call with a driver capability check: if (dataSource.driver.isReturningSqlSupported('delete')).","Drop .returning() and issue a follow-up SELECT by id before delete, or capture affected ids another way.","If you need DELETE ... RETURNING universally, use Postgres, SQL Server, or modern SQLite as the backing database.","Factor driver-specific delete logic behind a repository strategy that branches on connection.options.type."],"exampleFix":"// before\nconst res = await dataSource\n  .createQueryBuilder().delete()\n  .from(User).where('id = :id', { id })\n  .returning(['id', 'email']).execute(); // throws on MySQL\n\n// after\nif (dataSource.driver.isReturningSqlSupported('delete')) {\n  return dataSource.createQueryBuilder().delete().from(User)\n    .where('id = :id', { id }).returning(['id', 'email']).execute();\n}\nconst existing = await dataSource.getRepository(User).findOne({ where: { id } });\nawait dataSource.getRepository(User).delete(id);\nreturn existing;","handlingStrategy":"validation","validationCode":"function supportsDeleteReturning(ds: DataSource): boolean {\n  return ds.driver.isReturningSqlSupported('delete');\n}\nif (!supportsDeleteReturning(dataSource)) { /* fall back to select-before-delete */ }","typeGuard":"function supportsReturning(driver: import('../driver/Driver').Driver, op: 'insert'|'update'|'delete'): boolean {\n  return driver.isReturningSqlSupported(op);\n}","tryCatchPattern":"try {\n  return qb.delete().from(E).where(...).returning(cols).execute();\n} catch (e) {\n  if (e instanceof ReturningStatementNotSupportedError) { /* select-before-delete fallback */ }\n  throw e;\n}","preventionTips":["Check driver.isReturningSqlSupported('delete') before .returning().","Prefer repository.delete(id) for portable code.","Keep driver-specific RETURNING paths behind a strategy that branches on connection.options.type.","Document which DBs each code path supports in the feature module."],"tags":["query-builder","delete","returning","driver-capability"],"backgroundTag":null,"analyzedSha":"5ac6606e81f67bb9534255570cd4e86fd8101eee","analyzedAt":"2026-08-12T05:26:35.080Z","schemaVersion":2},"datasetVersion":"2026-08-12T18:17:37.767Z"}