Upgrade impact preview
What breaks when you upgrade ERPNext?breaking changes in ERPNext v14, v15 and v16, by kind of customisation
Pick your version and what you have built on it. See the changes Frappe documents as breaking for those things, each with its source.
Nothing is read from your site, and your ticks stay in your browser.
Your versions
Not sure which? bench version on the server prints it. The free check reads it too.
v14: end of life 31 January 2026 · v15: end of 2027 (planned) · v16: end of 2029 (planned). Frappe's support table, read 14 October 2026.
What you have built
Tick everything that applies. Tick nothing to see every documented change.
Start from
24 documented changes touch the 3 kinds you ticked, v14 to v16.
10 stop working, 13 behave differently and 1 documented as not affected.
What Frappe documents for your list
- No mark: the source names this kind.
- If your code uses it: the source names a function, setting or address, so it matters only if your code uses it.
- Our reading: the source does not name this kind. We read it as likely to matter.
Stops working 10
- What changes
- Client scripts lose access to local variables such as this. Frappe says that use was never intended.
- What to do
- Find those lines and rewrite them without this.
- Find it
- this. inside a Client Script
- Source
- Migrating to version 15 (Frappe wiki on GitHub), section “Access to local scope by client scripts is no longer supported”
- What changes
- Most helpers Frappe once put on window are removed: get_today, date, dateutil, show_alert, validated, user, user_fullname, user_email, user_defaults, roles, sys_defaults.
- What to do
- Swap each for its frappe.* name, for example frappe.datetime.get_today or frappe.show_alert. The wiki has the full table.
- Find it
- get_today( show_alert( user_fullname roles sys_defaults
- Source
- Migrating to version 15 (Frappe wiki on GitHub), section “window globals removed”
- What changes
- An app could ship one client script per doctype in /fixtures/custom_scripts. That import is removed. Frappe now recommends normal fixtures.
- What to do
- Move those scripts into the app's fixtures.
- Find it
- a fixtures/custom_scripts folder in a custom app
- Source
- Migrating to version 15 (Frappe wiki on GitHub), section “Removal of custom script import from /fixtures/custom_scipts”
- What changes
- These options are removed. Updates already run in one query, so for_update is not needed.
- What to do
- Drop the arguments.
- Find it
- as_utf8 formatted= for_update
- Source
- Migrating to version 15 (Frappe wiki on GitHub), section “Removed database methods”Also: Script API, “Database”
- What changes
- The generic hierarchy chart JS classes and the html2canvas dependency left ERPNext. They live in the hrms app now.
- What to do
- Install hrms, or copy what you use into a custom app.
- Find it
- hierarchy chart classes html2canvas
- Source
- Migration Guide to ERPNext version 15 (ERPNext wiki on GitHub), section “Hierarchy Chart moved to Frappe HR”
- What changes
- Function strings such as sum(qty) as total are no longer supported. The same goes for distinct in the field list, ifnull(...) in filters and literal values in fields. Use the dict form or query builder functions. run=False now returns a QueryBuilder, not a string.
- What to do
- Rewrite each call. The query builder guide has before and after code.
- Find it
- fields with ( in get_all, get_list or db.get_all; distinct; ifnull
- Source
- query builder migration (Frappe wiki on GitHub), section “Biggest change: function usage”Also: Migrating to version 16, “Usage of query builder for get_list and get_all”; Migrating to version 16, “SQL function syntax changes”
- What changes
- The whitelisted method erpnext.accounts.doctype.bank_account.bank_account.make_bank_account is gone. Create party-linked Bank Accounts with frappe.new_doc in the frontend.
- What to do
- Replace calls to it.
- Find it
- make_bank_account
- Source
- Migration Guide To ERPNext Version 16 (ERPNext wiki on GitHub), section “New Party Bank Account via API”
- What changes
- The whitelisted method make_pricing_rule and the frontend util erpnext.utils.make_pricing_rule are gone. Create party-linked Pricing Rules with frappe.new_doc in the frontend.
- What to do
- Replace calls to them.
- Find it
- make_pricing_rule
- Source
- Migration Guide To ERPNext Version 16 (ERPNext wiki on GitHub), section “New Pricing Rule via API”
- What changes
- The item_wise_tax_detail JSON on each tax row is replaced by the Item Wise Tax Detail child table. Frappe says this affects custom tax calculation logic, reports that read tax breakdowns and integrations that manipulate tax data.
- What to do
- Read the child table instead of parsing JSON. If you set taxes by hand, follow the guide: dont_recompute_tax and the _item_wise_tax_details list.
- Find it
- item_wise_tax_detail
- Source
- Migration Guide To ERPNext Version 16 (ERPNext wiki on GitHub), section “Item Wise Tax Details: JSON → Child Table”Also: Item Wise Tax Details: JSON → Child Table, “Impact”
- What changes
- TDS and TCS detail now lives in the Tax Withholding Entry child table on all documents. The old advance_tax and tax_withheld_vouchers tables are replaced, and TDS on Purchase Order and Purchase Receipt is removed. The upgrade migrates the data.
- What to do
- Point custom TDS reports, print formats and scripts at the new table.
- Find it
- advance_tax tax_withheld_vouchers is_tax_withholding_account
- Source
- Migration Guide To ERPNext Version 16 (ERPNext wiki on GitHub), section “Tax Withholding Entry”Also: Tax Withholding Entry, “What Changed in v16”; Tax Withholding Entry, “Removed Features”
Behaves differently 13
- What changes
- The Serial No and Batch No fields on transaction rows were replaced by a link to a Serial and Batch Bundle. Print formats must read the numbers from the bundle, for example with get_serial_or_batch_nos(bundle_id).
- What to do
- Update print formats, reports and scripts that read serial_no or batch_no from the row.
- Find it
- serial_no batch_no
- Source
- Migration Guide to ERPNext version 15 (ERPNext wiki on GitHub), section “Serial and Batch Bundle”
- What changes
- Dunning no longer links to a single Sales Invoice. It has a table of overdue payments, each linking to an invoice. Frappe asks you to adjust scripts and print formats.
- What to do
- Adjust scripts and print formats that read the old link.
- Find it
- Dunning
- Source
- Migration Guide to ERPNext version 15 (ERPNext wiki on GitHub), section “Dunning”
- What changes
- It takes the current time only if its options say Now.
- What to do
- Set Now in the options of Time fields that relied on the default.
- Find it
- Time fields, custom ones included
- Source
- Migrating to version 16 (Frappe wiki on GitHub), section “Default value removed from the time field”
- What changes
- Frappe's 16.50 announcement says it has no breaking changes except some form cleanups that might have moved your custom fields around.
- What to do
- After you reach 16.50 or later, open your busiest forms and check where custom fields sit.
- Find it
- the forms your team uses most
- Source
- Announcing Framework, ERPNext and HRMS v16.50 (Frappe blog), section “How do I migrate? Will things break?”
- What changes
- Custom screens that call frappe.desk.search.search_link must read r.message instead of r.results.
- What to do
- Change the key in the callback.
- Find it
- search_link search_widget
- Source
- Migrating to version 15 (Frappe wiki on GitHub), section “search_link and search_widget response type”
- What changes
- The report was renamed.
- What to do
- Update shortcuts, saved links and scripts that open it by name.
- Find it
- TDS Payable Monthly
- Source
- Migration Guide to ERPNext version 15 (ERPNext wiki on GitHub), section “TDS Payable Monthly Report”
- What changes
- The desk frontend is rerouted from /app to /desk, and the /apps page is deprecated.
- What to do
- Search your scripts, email templates and integrations for hard-coded /app/ links.
- Find it
- /app/
- Source
- Migrating to version 16 (Frappe wiki on GitHub), section “Changes to Navigation”
- What changes
- get_all, get_list, db.get_value, db.get_values and qb.get_query now sort by creation by default. List views do too.
- What to do
- Add order_by='modified desc' wherever the order matters. Re-add a modified index if you need one.
- Find it
- get_all( get_list( get_value( with no order_by
- Source
- Migrating to version 16 (Frappe wiki on GitHub), section “Default sorting changed from modified to creation”
- What changes
- It used to return strings. Now it returns numbers and booleans, so a test like == "1" must become == 1.
- What to do
- Search for comparisons on settings values.
- Find it
- db.get_value on settings doctypes
- Source
- Migrating to version 16 (Frappe wiki on GitHub), section “db.get_value casts single doctype results”
- What changes
- State-changing methods reject GET. Client code that calls them with GET must switch to POST.
- What to do
- Change those calls.
- Find it
- /api/method/logout upload_file send_login_link
- Source
- Migrating to version 16 (Frappe wiki on GitHub), section “Some whitelisted methods now require POST”
- What changes
- Code that relied on virtual fields appearing in that list must change.
- What to do
- Check where you call it.
- Find it
- get_valid_columns
- Source
- Migrating to version 16 (Frappe wiki on GitHub), section “meta.get_valid_columns() now excludes virtual fields”
- What changes
- Before, it did not produce the expected IS NOT NULL clause, so results could be wrong.
- What to do
- Re-check queries that filter with != None.
- Find it
- != None in filters
- Source
- Migrating to version 16 (Frappe wiki on GitHub), section “Handle != None condition correctly in db_query”
- What changes
- The Awesome Bar lives in the sidebar (cmd + k). User settings and notifications moved. Saved filters sit on top and quick filters are per user. Frappe lists these as UI changes.
- What to do
- Check scripts that add to or read the list sidebar.
- Find it
- list sidebar awesome bar
- Source
- Migrating to version 16 (Frappe wiki on GitHub), section “List View”
Documented as not affected 1
- What changes
- Frappe says HTML (Jinja) print formats are not affected by the classic print format deprecation.
- What to do
- Nothing to convert. Other rows may still apply to the Jinja inside.
- Source
- Migrating to version 16 (Frappe wiki on GitHub), section “Classic print formats are deprecated”
This list shows what could break, not what will
Three steps from this list to an answer for your site: count what you have, search for the Find lines, then have it read.
A free, read-only script that counts what you have: custom fields, scripts, print formats, reports, roles and, on your own server, edited core files. Never your data.
Free and read-only: it counts, and never reads your data.
For your list it counts: Custom fields and form changes, Client scripts and 1 more.It cannot see: nothing on your list.
Each row ends with a Find line: names to search for in your scripts, apps and templates. A hit means check it. No hit is a good sign, not a promise.
You search your own code; nothing is sent.
- Client scripts can no longer use thisthis. inside a Client Script
- Old window globals are gone: get_today, show_alert, user, rolesget_today( show_alert( user_fullname roles sys_defaults
- Client scripts in /fixtures/custom_scripts no longer synca fixtures/custom_scripts folder in a custom app
- db.sql loses as_utf8 and formatted; db.set_value loses for_updateas_utf8 formatted= for_update
Send us your versions and what you ticked. We will say what we would check first. The ERPNext declutter audit also reads custom code.
You read and can edit the note before it is sent.
The note Talk to us carries
Upgrade impact: v14 to v16. Ticked: Custom fields and form changes, Client scripts, Jinja in print formats.
What this checker answers
Which documented changes touch what you built, before you upgrade ERPNext.
It reads nothing from your site, so a row says what could break, never what will. For a real upgrade the list is where the test plan starts: try each change on a copy of your site first.
What it rests on
- Frappe and ERPNext release notesThe documented breaking changes, linked per row.
- The code change behind each rowThe pull request or commit, where Frappe's notes point to one.
- Rows marked as our readingWhere a change is not labelled breaking but touches custom code, the row says so.
What the list leaves out, and where it comes from
Five things this list does not cover, and the pages every line is read from.
- Your codeNothing is read from your site, so a row says what could break, not what will. For a custom app moving to v16, start here.
- Point releasesv15.x and v16.x releases can list their own breaking changes in their release notes. This list takes the migration pages and release 16.50.
- Other appsFrappe HR, India Compliance and other apps have their own release notes. This list does not read them.
- Skipping a versionFrappe's pages are written one version at a time and do not say whether skipping is supported. For v14 to v16 this list stacks both.
- LikelihoodNo row says how likely it is to hit you.
The sources
16pages, all read on 14 October 2026
Latest releases that day: Frappe v16.52.0, v15.123.0 and v14.101.1. Where two sources disagree, both are shown: the 16.50 announcement says there are no breaking changes beyond form cleanups, and the ERPNext 16.50.0 release notes list two.
When the upgrade is a project
Upgrades sit with support today. These are the next steps once you have the list.
Plan your upgrade on a call
Bring the list; we say what we would test first.
ERPNext support and AMC
Upgrades, fixes and monitoring under one contract.
ERPNext declutter
When the upgrade turns up years of workarounds.
Questions about upgrades
The one most people ask is answered first. Type to find the rest.
Do my custom fields, scripts and print formats survive an ERPNext upgrade?
Not all of them. v16 resets edits to standard workspaces, and v15 switches server scripts off until you turn them on. Others stay in place but fail when they run, if they call something that changed. The list above ties each documented change to the kinds it touches.
What breaks
17 documented changes touch client scripts, server scripts or old-style form scripts when you move from v14 to v15. Among them: server scripts are off by default and must be enabled for the bench, client scripts can no longer use "this", and old window globals such as get_today and show_alert are gone. Tick those kinds with v14 to v15 to see all 17.
Mostly database calls. get_all and get_list now reject SQL strings such as sum(qty) as total, lists sort by creation instead of modified, and db.get_value on settings returns real types. Tax detail and TDS data moved to new tables. Tick Custom reports and Jinja in print formats with v15 to v16 for the full list.
No. Frappe says HTML (Jinja) print formats are not affected. Classic formats, made in the old builder, still print in v16 but stop working in v17, and they print through Chromium once converted. Other changes can still touch the Jinja inside a format, such as database calls and tax tables.
Versions
Frappe's pages are written for each version separately and do not say whether skipping a version is supported. This tool stacks the changes of v15 and v16 for v14 to v16, so you see everything Frappe lists for both. How you run the move, directly or through v15, is a plan for a staging copy. Ask us.
Frappe's support table lists 31 January 2026 as the end of life for version 14. Version 15 is listed to the end of 2027 and version 16 to the end of 2029, both marked planned. Frappe's table is the source, and it was read on 14 October 2026.
This tool
No. It works from Frappe's published pages, in your browser. Our analytics record your versions, how many boxes you ticked, how many changes the list showed, which changes you open, and whether you copy the list, run the free check or open Talk to us. They never record which kinds you ticked. The Talk to us note carries what you ticked only if you send it.
Frappe lists changes by version. This sorts the same list by what you have built, and puts the source on every line. It adds nothing Frappe has not documented. Where a row is our reading of a documented change, it says so.