Payment Entry has been modified after you pulled it Issue on Development

I have a custom subscription implementation with the following structure:

  • 1 Sales Order per subscription

  • 1 Payment Entry (full advance paid upfront)

  • Multiple Sales Invoices created programmatically — one per delivery

  • Multiple Delivery Notes — one per delivery

Each SI is created via a whitelisted API method and allocates a portion of the PE’s unallocated_amount as an advance.

The Error:

When submitting the SI, ERPNext throws:

Payment Entry has been modified after you pulled it. Please pull it again.
Below Is My actual Code and the ERROR:
def create_sales_invoice_subscription(soname, subscription_delivery):
    try:
        sd = subscription_delivery
        """
        {
            "subscription_id":"SUB100",
            "delivery_id": "1234",
            "delivery_date":"19-02-2026",
            "delivery_slot":"10:00AM - 11:00AM",
            "item_code":"ITEM100",
            "warehouse_id":"WH100",
            "rate:"12",
            "quantity":"10"

        }
        
        """
        print(subscription_delivery)
        if isinstance(subscription_delivery, str):
            subscription_delivery = json.loads(subscription_delivery)
        so = frappe.get_doc("Sales Order", soname)
        sm = frappe.get_doc("Subscription Master", sd.get("subscription_id"))

        pe = frappe.get_doc("Payment Entry", sm.payment_entry)
        pe.reload()


        si = frappe.new_doc("Sales Invoice")

        # si.series = "SUB"
        si.customer = so.customer
        si.company = so.company
        si.currency = "INR"
        si.posting_date = getdate(sd.get("delivery_date")) or nowdate()
        si.set_posting_time = 1

        si.append("items", {
            "item_code": sd.get("item_code"),
            "qty": float(sd.get("quantity")),
            "rate": float(sd.get("rate")),
            "warehouse": sd.get("warehouse_id"),
            "income_account": "41100004 - Sales of Finished Goods - Subscription - DV"
        })
            

        #"Get advance Payments"
        si.insert(ignore_permissions=True)

        print("PE UNALLOCATED AMOUNT", pe.unallocated_amount)
        if pe.unallocated_amount <= 0:
            frappe.log_error("No advance balance available in linked Payment Entry")
            return

        allocate_amount = min(pe.unallocated_amount, si.grand_total)

        si.append("advances", {
            "reference_type": "Payment Entry",
            "reference_name": pe.name,
            "advance_amount": pe.paid_amount,
            "allocated_amount": allocate_amount,
            "difference_posting_date": getdate(sd.get("delivery_date")) or nowdate()
        })
        si.save(ignore_permissions=True)

        si.submit()

        return si
    except Exception as e:
        frappe.throw(f"Error creating sales invoice: {str(e)}", "Order Sync")
        return None
{
    "exception": "frappe.exceptions.ValidationError: Error creating sales invoice: Payment Entry has been modified after you pulled it. Please pull it again.",
    "exc_type": "ValidationError",
    "_exc_source": "delish_vault (app)",
    "exc": "[\"Traceback (most recent call last):\\n  File \\\"apps/delish_vault/delish_vault/order_sync/order_documents.py\\\", line 333, in create_sales_invoice_subscription\\n    si.submit()\\n  File \\\"apps/frappe/frappe/utils/typing_validations.py\\\", line 32, in wrapper\\n    return func(*args, **kwargs)\\n  File \\\"apps/frappe/frappe/model/document.py\\\", line 1097, in submit\\n    return self._submit()\\n  File \\\"apps/frappe/frappe/model/document.py\\\", line 1080, in _submit\\n    return self.save()\\n  File \\\"apps/frappe/frappe/model/document.py\\\", line 378, in save\\n    return self._save(*args, **kwargs)\\n  File \\\"apps/frappe/frappe/model/document.py\\\", line 431, in _save\\n    self.run_post_save_methods()\\n  File \\\"apps/frappe/frappe/model/document.py\\\", line 1180, in run_post_save_methods\\n    self.run_method(\\\"on_submit\\\")\\n  File \\\"apps/frappe/frappe/model/document.py\\\", line 1011, in run_method\\n    out = Document.hook(fn)(self, *args, **kwargs)\\n  File \\\"apps/frappe/frappe/model/document.py\\\", line 1371, in composer\\n    return composed(self, method, *args, **kwargs)\\n  File \\\"apps/frappe/frappe/model/document.py\\\", line 1353, in runner\\n    add_to_return_value(self, fn(self, *args, **kwargs))\\n  File \\\"apps/frappe/frappe/model/document.py\\\", line 1008, in fn\\n    return method_object(*args, **kwargs)\\n  File \\\"apps/erpnext/erpnext/accounts/doctype/sales_invoice/sales_invoice.py\\\", line 480, in on_submit\\n    self.update_against_document_in_jv()\\n  File \\\"apps/erpnext/erpnext/controllers/accounts_controller.py\\\", line 1899, in update_against_document_in_jv\\n    reconcile_against_document(lst, active_dimensions=active_dimensions)\\n  File \\\"apps/erpnext/erpnext/accounts/utils.py\\\", line 482, in reconcile_against_document\\n    check_if_advance_entry_modified(entry)\\n  File \\\"apps/erpnext/erpnext/accounts/utils.py\\\", line 593, in check_if_advance_entry_modified\\n    throw(_(\\\"\\\"\\\"Payment Entry has been modified after you pulled it. Please pull it again.\\\"\\\"\\\"))\\n  File \\\"apps/frappe/frappe/__init__.py\\\", line 609, in throw\\n    msgprint(\\n  File \\\"apps/frappe/frappe/__init__.py\\\", line 574, in msgprint\\n    _raise_exception()\\n  File \\\"apps/frappe/frappe/__init__.py\\\", line 525, in _raise_exception\\n    raise exc\\nfrappe.exceptions.ValidationError: Payment Entry has been modified after you pulled it. Please pull it again.\\n\\nDuring handling of the above exception, another exception occurred:\\n\\nTraceback (most recent call last):\\n  File \\\"apps/frappe/frappe/app.py\\\", line 120, in application\\n    response = frappe.api.handle(request)\\n  File \\\"apps/frappe/frappe/api/__init__.py\\\", line 52, in handle\\n    data = endpoint(**arguments)\\n  File \\\"apps/frappe/frappe/api/v1.py\\\", line 40, in handle_rpc_call\\n    return frappe.handler.handle()\\n  File \\\"apps/frappe/frappe/handler.py\\\", line 52, in handle\\n    data = execute_cmd(cmd)\\n  File \\\"apps/frappe/frappe/handler.py\\\", line 85, in execute_cmd\\n    return frappe.call(method, **frappe.form_dict)\\n  File \\\"apps/frappe/frappe/__init__.py\\\", line 1754, in call\\n    return fn(*args, **newargs)\\n  File \\\"apps/frappe/frappe/utils/typing_validations.py\\\", line 32, in wrapper\\n    return func(*args, **kwargs)\\n  File \\\"apps/delish_vault/delish_vault/order_sync/order_documents.py\\\", line 337, in create_sales_invoice_subscription\\n    frappe.throw(f\\\"Error creating sales invoice: {str(e)}\\\", \\\"Order Sync\\\")\\n  File \\\"apps/frappe/frappe/__init__.py\\\", line 609, in throw\\n    msgprint(\\n  File \\\"apps/frappe/frappe/__init__.py\\\", line 574, in msgprint\\n    _raise_exception()\\n  File \\\"apps/frappe/frappe/__init__.py\\\", line 525, in _raise_exception\\n    raise exc\\nfrappe.exceptions.ValidationError: Error creating sales invoice: Payment Entry has been modified after you pulled it. Please pull it again.\\n\"]",
    "_server_messages": "[\"{\\\"message\\\": \\\"Payment Entry has been modified after you pulled it. Please pull it again.\\\", \\\"title\\\": \\\"Message\\\", \\\"indicator\\\": \\\"red\\\", \\\"raise_exception\\\": 1, \\\"__frappe_exc_id\\\": \\\"1a7b8fec4c235a1bf53bd4748d0534b86eade2bd98be1fed53c9251e\\\"}\", \"{\\\"message\\\": \\\"Error creating sales invoice: Payment Entry has been modified after you pulled it. Please pull it again.\\\", \\\"title\\\": \\\"Message\\\", \\\"indicator\\\": \\\"red\\\", \\\"raise_exception\\\": 1, \\\"__frappe_exc_id\\\": \\\"57aa60b7c4c3f1e13be015d65cb19ce373d98e6ca7b7e5a113713580\\\"}\"]"
}