Error Summary
When creating a Purchase Invoice via the API (POST to /api/resource/Purchase Invoice), a TypeError is raised due to base_write_off_amount being treated as None, even though the value 0.0 is explicitly provided.
TypeError: unsupported operand type(s) for -: 'NoneType' and 'float'
It happens inside:
base_grand_total = base_grand_total - flt(self.base_write_off_amount)
This line fails because self.base_write_off_amount is still None.
Request payload (from n8n)
{
"supplier": "Lieferant A",
"bill_no": "20240216",
"posting_date": "2024-05-07",
"net_total": 384,
"grand_total": 410.88,
"total_taxes_and_charges": 26.88,
"total": 410.88,
"currency": "EUR",
"purchase_order": "PO-10055",
"docstatus": 0,
"company": "Beispielfirma GmbH",
"item_name": "Produkt X 2,5 kg",
"qty": 200,
"rate": 1.8,
"write_off_amount": 0.0,
"base_write_off_amount": 0.0
}
Even when explicitly setting base_write_off_amount to 0.0 or "0.0", ERPNext internally processes it as None, which causes the flt() function to raise a TypeError during subtraction.
Expected Behavior
ERPNext should accept 0.0 as a valid float input and not convert it into None, preventing the error.
Additional Context
• Reproducible via HTTP POST from n8n, curl or Postman
• Problem persists even if other optional fields are removed
• Setting "base_write_off_amount": 0 or "0.0" has no effect
• The value is simply ignored in the document during validation phase
### Module
accounts
### Version
Frappe Framework - v15.74.1 (version-15)
ERPnext Version - v15.70.2 (version-15)
---
### **📦 Module**
`Accounts`
---
### **🧮 Version**
`v15.70.2`
---
Deployment: Self-hosted (LXC Container, Proxmox)
### Installation method
manual install
### Relevant log output / Stack trace / Full Error Message.
```shell
The service was not able to process your request
500 - "{\"exception\":\"TypeError: unsupported operand type(s) for -: 'NoneType' and 'float'\",\"exc_type\":\"TypeError\",\"_exc_source\":\"erpnext (app)\",\"exc\":\"[\\\"Traceback (most recent call last):\\\\n File \\\\\\\"apps/frappe/frappe/app.py\\\\\\\", line 115, in application\\\\n response = frappe.api.handle(request)\\\\n File \\\\\\\"apps/frappe/frappe/api/__init__.py\\\\\\\", line 49, in handle\\\\n data = endpoint(**arguments)\\\\n File \\\\\\\"apps/frappe/frappe/api/v1.py\\\\\\\", line 42, in create_doc\\\\n return frappe.new_doc(doctype, **data).insert()\\\\n File \\\\\\\"apps/frappe/frappe/model/document.py\\\\\\\", line 309, in insert\\\\n self.run_before_save_methods()\\\\n File \\\\\\\"apps/frappe/frappe/model/document.py\\\\\\\", line 1136, in run_before_save_methods\\\\n self.run_method(\\\\\\\"validate\\\\\\\")\\\\n File \\\\\\\"apps/frappe/frappe/model/document.py\\\\\\\", line 1007, in run_method\\\\n out = Document.hook(fn)(self, *args, **kwargs)\\\\n File \\\\\\\"apps/frappe/frappe/model/document.py\\\\\\\", line 1367, in composer\\\\n return composed(self, method, *args, **kwargs)\\\\n File \\\\\\\"apps/frappe/frappe/model/document.py\\\\\\\", line 1349, in runner\\\\n add_to_return_value(self, fn(self, *args, **kwargs))\\\\n File \\\\\\\"apps/frappe/frappe/model/document.py\\\\\\\", line 1004, in fn\\\\n return method_object(*args, **kwargs)\\\\n File \\\\\\\"apps/erpnext/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py\\\\\\\", line 262, in validate\\\\n super().validate()\\\\n File \\\\\\\"apps/erpnext/erpnext/controllers/buying_controller.py\\\\\\\", line 33, in validate\\\\n super().validate()\\\\n File \\\\\\\"apps/erpnext/erpnext/controllers/subcontracting_controller.py\\\\\\\", line 56, in validate\\\\n super().validate()\\\\n File \\\\\\\"apps/erpnext/erpnext/controllers/stock_controller.py\\\\\\\", line 52, in validate\\\\n super().validate()\\\\n File \\\\\\\"apps/erpnext/erpnext/controllers/accounts_controller.py\\\\\\\", line 261, in validate\\\\n self.validate_all_documents_schedule()\\\\n File \\\\\\\"apps/erpnext/erpnext/controllers/accounts_controller.py\\\\\\\", line 605, in validate_all_documents_schedule\\\\n self.validate_invoice_documents_schedule()\\\\n File \\\\\\\"apps/erpnext/erpnext/controllers/accounts_controller.py\\\\\\\", line 592, in validate_invoice_documents_schedule\\\\n self.set_payment_schedule()\\\\n File \\\\\\\"apps/erpnext/erpnext/controllers/accounts_controller.py\\\\\\\", line 2464, in set_payment_schedule\\\\n base_grand_total = base_grand_total - flt(self.base_write_off_amount)\\\\nTypeError: unsupported operand type(s) for -: 'NoneType' and 'float'\\\\n\\\"]\"}"
Additional N8N Information
Item Index
0
Node type
n8n-nodes-base.httpRequest
Node version
4.2 (Latest)
n8n version
1.104.2 (Self Hosted)
Time
30.7.2025, 17:53:12
Stack trace
NodeApiError: The service was not able to process your request at ExecuteContext.requestWithAuthentication (/usr/lib/node_modules/n8n/node_modules/n8n-core/src/execution-engine/node-execution-context/utils/request-helper-functions.ts:1463:10) at processTicksAndRejections (node:internal/process/task_queues:95:5) at ExecuteContext.requestWithAuthentication (/usr/lib/node_modules/n8n/node_modules/n8n-core/src/execution-engine/node-execution-context/utils/request-helper-functions.ts:1749:11)
Information on your n8n setup
- n8n version: 1.104.2
- Database (default: SQLite):
- n8n EXECUTIONS_PROCESS setting (default: own, main): main
- Running n8n via (Docker, npm, n8n cloud, desktop app): LXC Container via rpm
- Operating system: Debian