From 0e25a77a629b6196e5092641ee348bc47b361520 Mon Sep 17 00:00:00 2001 From: Mihir Kandoi Date: Sun, 21 Jun 2026 15:48:32 +0530 Subject: [PATCH 1/2] fix(postgres): savepoint Plaid bank-account creation loop add_bank_accounts() inserts a Bank Account per Plaid account in a loop. On a duplicate the bare insert raises UniqueValidationError, which on Postgres aborts the whole transaction; the handler only msgprint'd and continued, so the next iteration's insert died with InFailedSqlTransaction. Wrap each iteration in a savepoint and roll back to it in the handlers (the pattern frappe#40075 prescribes after dropping the blanket per-insert savepoint). No-op on MariaDB. --- .../doctype/plaid_settings/plaid_settings.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/erpnext/erpnext_integrations/doctype/plaid_settings/plaid_settings.py b/erpnext/erpnext_integrations/doctype/plaid_settings/plaid_settings.py index 51bc540937f..36c2f8c7fc8 100644 --- a/erpnext/erpnext_integrations/doctype/plaid_settings/plaid_settings.py +++ b/erpnext/erpnext_integrations/doctype/plaid_settings/plaid_settings.py @@ -113,6 +113,8 @@ def add_bank_accounts(response: str | dict, bank: str | dict, company: str): if not existing_bank_account: try: + # savepoint so a failed insert doesn't poison the transaction on postgres + frappe.db.savepoint("plaid_bank_account") gl_account = frappe.get_doc( { "doctype": "Account", @@ -142,12 +144,14 @@ def add_bank_accounts(response: str | dict, bank: str | dict, company: str): result.append(new_account.name) except frappe.UniqueValidationError: + frappe.db.rollback(save_point="plaid_bank_account") # preserve transaction in postgres frappe.msgprint( _("Bank account {0} already exists and could not be created again").format( account["name"] ) ) except Exception: + frappe.db.rollback(save_point="plaid_bank_account") # preserve transaction in postgres frappe.log_error("Plaid Link Error") frappe.throw( _("There was an error creating Bank Account while linking with Plaid."), From bac4f1de52387ac4de29f7b79d5e93f3d63d9ffc Mon Sep 17 00:00:00 2001 From: Mihir Kandoi Date: Sun, 21 Jun 2026 15:48:37 +0530 Subject: [PATCH 2/2] fix(postgres): savepoint bank-account creation during company setup create_bank_account() inserts a bank Account and swallows DuplicateEntryError ('bank account same as a CoA entry'). On Postgres the failed insert aborts the transaction, so the rest of company setup ran against a poisoned transaction. Take a savepoint and roll back to it in the handler. No-op on MariaDB. --- erpnext/setup/setup_wizard/operations/install_fixtures.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/erpnext/setup/setup_wizard/operations/install_fixtures.py b/erpnext/setup/setup_wizard/operations/install_fixtures.py index 806db071963..1d1edeaf949 100644 --- a/erpnext/setup/setup_wizard/operations/install_fixtures.py +++ b/erpnext/setup/setup_wizard/operations/install_fixtures.py @@ -567,6 +567,7 @@ def create_bank_account(args, demo=False): } ) try: + frappe.db.savepoint("create_bank_account") doc = bank_account.insert() if args.get("set_default"): @@ -583,6 +584,7 @@ def create_bank_account(args, demo=False): except RootNotEditable: frappe.throw(frappe._("Bank account cannot be named as {0}").format(args.get("bank_account"))) except frappe.DuplicateEntryError: + frappe.db.rollback(save_point="create_bank_account") # preserve transaction in postgres # bank account same as a CoA entry pass