Frappe ops upgrades
Skill Impertio-Studio/Frappe_Claude_Skill_Package/skills/source/ops/frappe-ops-upgrades
Use when upgrading Frappe/ERPNext between major versions (v14 to v15, v15 to v16), troubleshooting failed migrations, or planning rollback. Prevents broken upgrades from skipped patches, incompatible customizations, and missing pre-upgrade checks. Covers version upgrade paths, bench update, migrate command, patch troubleshooting, rollback procedures, breaking changes per version. Keywords: upgrade, migration, v14, v15, v16, bench update, bench migrate, rollback, patches, breaking changes, update failed, bench update error, migration error, patches failing, rollback after upgrade..From its SKILL.md
npx -y skills add Impertio-Studio/Frappe_Claude_Skill_Package --skill frappe-ops-upgradesAssembled from the repository path, not quoted from the project. Check it against their README if it does not work.
One thing to look at
- no licenseNo license file was found in the repository. Code published without one is not open source by default, so using it at work is a question for whoever answers licensing questions where you are.
What its file declares
Copied from the file, not written here
The file declares its own license as MIT. That is the author’s claim about this one file, and it is not the same thing as the license GitHub reports for the repository, which is listed with the other numbers below.
SKILL.md
13.2 KB, ~3.2k tokens by cl100k_base, as published. Nobody here has run it
Version Upgrades
Complete guide for upgrading Frappe/ERPNext between major versions, handling failed migrations, and rolling back safely.
Versions: v14 → v15 → v16
Quick Reference: Upgrade Commands
| Task | Command |
|---|---|
| Full update | bench update |
| Update specific app | bench update --pull --app erpnext |
| Switch branch | bench switch-to-branch version-15 frappe erpnext |
| Run migrations only | bench --site mysite migrate |
| Check migration readiness | bench --site mysite ready-for-migration |
| Backup before upgrade | bench --site mysite backup |
| Restore from backup | bench --site mysite restore /path/to/backup.sql.gz |
| Re-run failed patch | Add #YYYY-MM-DD suffix in patches.txt |
Decision Tree: Upgrade Strategy
Need to upgrade?
├── Single minor version bump (e.g., v15.10 → v15.20)?
│ └── YES → Run `bench update` directly
├── Major version jump (e.g., v14 → v15)?
│ ├── Have custom apps?
│ │ ├── YES → Test on staging FIRST, check breaking changes
│ │ └── NO → Follow standard upgrade path
│ └── Multiple major versions (v14 → v16)?
│ └── ALWAYS upgrade one version at a time: v14 → v15 → v16
└── Production environment?
├── YES → ALWAYS test on staging clone first
└── NO → Proceed with standard upgrade
Pre-Upgrade Checklist
ALWAYS complete these steps before ANY major version upgrade:
- Full backup —
bench --site mysite backup --with-files - Test on staging — Clone production to a staging bench and test there first
- Check breaking changes — Review the breaking changes section below
- Audit custom apps — Run custom apps against new version's API changes
- Check Python/Node versions — v15 requires Node 18+; v16 requires Node 24+, Python 3.14+
- Disable scheduler —
bench --site mysite scheduler disable - Check pending jobs —
bench --site mysite ready-for-migration - Read release notes — Check GitHub release notes for each version
Standard Upgrade Process
Step-by-Step
# 1. Backup all sites
bench backup-all-sites
# 2. Switch to target version branch
bench switch-to-branch version-15 frappe erpnext
# 3. Update (pulls code, installs deps, builds, migrates)
bench update
# 4. Verify
bench --site mysite migrate # if not done by update
bench version # confirm versions
What bench update Executes (In Order)
- Backup all sites
- Pull latest code for all apps (
git pull) - Install Python requirements (
pip install) - Install Node requirements (
yarn install) - Build static assets (
bench build) - Run migrations on all sites (
bench migrate) - Restart bench processes
v14 → v15 Breaking Changes
Environment Requirements
| Requirement | v14 | v15 |
|---|---|---|
| Node.js | v14+ | v18+ |
| Python packaging | setup.py | pyproject.toml |
Backend Breaking Changes
db.set()removed — Usedoc.db_set()insteaddb.sql()parameters removed —as_utf8andformattedno longer accepteddb.set_value()for Singles — Usefrappe.db.set_single_value()insteadjob_namedeprecated — Usejob_idparameter inenqueue()frappe.new_doc()arguments —parent_doc,parentfield,as_dictMUST be keyword argsfrappe.get_installed_apps()— No longer acceptssortorfrappe_lastargs- Method override order reversed — Last override now takes precedence
- Timezone functions renamed —
convert_utc_to_user_timezone→convert_utc_to_system_timezone
Frontend Breaking Changes
- Vue 2 → Vue 3 — All Vue components MUST be migrated
- Window globals removed —
get_today→frappe.datetime.get_today,user→frappe.session.user thisin Client Scripts — Local scope access no longer supported- Image lazy loading — Replace
website-image-lazyclass with nativeloading="lazy"
Security Changes
- Server Scripts disabled by default — Enable:
bench set-config -g server_script_enabled 1 - "Desk User" role added — Replaces "All" role for desk user permissions
currentsite.txtremoved — Usebench use sitenameorFRAPPE_SITEenv var
Removed Features
- Event Streaming moved to separate app
- Cordova support removed
setup.pyremoved (usepyproject.toml)--make_copyand--restorebuild flags removed (use--hard-link)
See breaking-changes.md for the complete list.
v15 → v16 Breaking Changes
Environment Requirements
| Requirement | v15 | v16 |
|---|---|---|
| Node.js | v18+ | v24+ |
| Python | 3.10+ | 3.14+ |
Backend Breaking Changes
- Default sort order changed —
creationinstead ofmodifiedfor all list queries has_permissionhooks — MUST return explicitTrue;Noneno longer acceptedfrappe.get_doc(doctype, name, field=value)— No longer updates values- DB commits in document hooks — No longer allowed to prevent data integrity issues
frappe.sendmail(now=True)— No longer commits transactions implicitlydb.get_value()for Singles — Now returns proper types instead of strings- State-changing methods require POST —
/api/method/logout,/api/method/upload_file, etc.
Separated Modules (Install Separately)
- Energy Points →
frappe/eps - Newsletter →
frappe/newsletter - Backup Integrations →
frappe/offsite_backups - Blog →
frappe/blog
Frontend Breaking Changes
- Report/Dashboard/Page JS evaluated as IIFEs (no global scope pollution)
- Awesome Bar redesigned, moved to sidebar (
Cmd+K) - List view right sidebar removed
/appsendpoint deprecated;/appreroutes to/desk
Configuration Changes
- Site config cached for up to one minute (changes not immediate)
- Country field requires valid ISO 3166 ALPHA-2 code
bench versionoutput format changed to "plain" (use-f legacyfor old format)override_doctypehook classes MUST inherit from the overridden class
See breaking-changes.md for the complete list.
Patch System
How Patches Work
Patches are one-off data migration scripts that run during bench migrate. They are defined in each app's patches.txt file.
patches.txt Format [v14+]
[pre_model_sync]
# Runs BEFORE schema sync — use for data prep
myapp.patches.v15_0.prepare_data_for_migration
[post_model_sync]
# Runs AFTER schema sync — use for data that needs new schema
myapp.patches.v15_0.migrate_data_to_new_fields
Patch Execution Rules
- Patches run in the order defined in
patches.txt - Each patch runs exactly ONCE — tracked in the
__patchestable - To re-run a patch, append a date comment:
myapp.patches.v15_0.fix #2025-03-20 - One-off statements:
execute:frappe.delete_doc('Page', 'old_page', ignore_missing=True)
Writing a Patch
# myapp/patches/v15_0/migrate_field_data.py
import frappe
def execute():
# ALWAYS reload if you need the NEW schema
frappe.reload_doc("module_name", "doctype", "doctype_name")
# Perform data migration
frappe.db.sql("""
UPDATE `tabSales Invoice`
SET new_field = old_field
WHERE old_field IS NOT NULL
""")
Debugging Stuck Patches
# Check which patches have run
bench --site mysite console
>>> frappe.db.sql("SELECT * FROM __patches WHERE patch LIKE '%stuck_patch%'")
# Remove a patch record to force re-run
>>> frappe.db.sql("DELETE FROM __patches WHERE patch = 'myapp.patches.v15_0.broken_patch'")
>>> frappe.db.commit()
# Then re-run migrate
bench --site mysite migrate
Rollback Procedure
Immediate Rollback (Within Hours)
# 1. Stop all processes
bench stop
# 2. Restore database from pre-upgrade backup
bench --site mysite restore /path/to/pre-upgrade-backup.sql.gz \
--with-public-files /path/to/files.tar \
--with-private-files /path/to/private-files.tar
# 3. Switch back to previous version branch
bench switch-to-branch version-14 frappe erpnext
# 4. Install old dependencies
bench setup requirements
# 5. Build old assets
bench build
# 6. Start bench
bench start # or: sudo bench restart (production)
Critical Rules for Rollback
- ALWAYS keep pre-upgrade backups for at least 7 days
- NEVER run
bench migrateafter restoring to old branch — schema is already correct - ALWAYS restore files alongside database — file references may break otherwise
- NEVER attempt rollback after users have created new data on the upgraded version
Frappe Packages: Moving Customizations Between Sites
Frappe Packages (v14+) are lightweight UI-built applications — bundles of Custom Module Defs distributed as .tar.gz tarballs. For Custom Fields, Property Setters, and DocPerms on standard DocTypes, use Fixtures instead.
Quick Reference: Package vs Fixtures vs App
| Mechanism | Use When | CLI Command |
|---|---|---|
| Package | UI-built DocTypes, Scripts, Web Pages | UI only (Package Import/Release) |
| Fixtures | Custom Fields, Property Setters, DocPerms | bench --site mysite export-fixtures |
| Frappe App | Full development workflow, CI/CD, tests | bench get-app, bench install-app |
Package Workflow (UI-Based)
- Create a Package document → assign Custom Module Defs to it
- Create a Package Release → exports to
[bench]/sites/[site]/packages/as[package]-[version].tar.gz - On target site, create Package Import → attach tarball, check Activate
- System migrates data like an app migration; use Force to overwrite existing files
Fixtures Workflow (CLI-Based)
# hooks.py — define what to export
fixtures = [
"Custom Field",
"Property Setter",
{"dt": "Client Script", "filters": [["module", "=", "My Module"]]}
]
# Export fixtures to JSON in your app
bench --site mysite export-fixtures --app myapp
# Fixtures auto-sync on: bench --site mysite migrate
NEVER use Packages to modify standard/core DocTypes — use a Frappe App with Fixtures.
See frappe-packages.md for the complete reference including decision trees, limitations, and best practices.
Custom App Compatibility Checks
Before upgrading, audit each custom app:
- Check deprecated APIs — Search for removed functions listed in breaking changes
- Check
setup.py— Must migrate topyproject.tomlfor v15+ - Check Vue components — Must be Vue 3 compatible for v15+
- Check
patches.txt— Ensure patches use[pre_model_sync]/[post_model_sync]sections [v14+] - Check hooks.py — Verify no removed hooks are used
- Run tests —
bench --site test_site run-tests --app myapp
Decision Tree: In-Place vs Fresh Install
Choosing upgrade strategy:
├── Small site (< 10 GB database)?
│ └── In-place upgrade is usually fine
├── Large site (> 50 GB database)?
│ ├── Many custom apps? → Fresh install + data migration
│ └── Standard apps only? → In-place with extended downtime window
├── Skipping multiple versions (v13 → v15)?
│ └── ALWAYS fresh install — sequential upgrades are too risky
└── Critical production with zero-downtime requirement?
└── Fresh install on parallel server + DNS switch
Version Differences Summary
| Feature | v14 | v15 | v16 |
|---|---|---|---|
| Python packaging | setup.py | pyproject.toml | pyproject.toml |
| Vue version | Vue 2 | Vue 3 | Vue 3 |
| Node.js minimum | v14 | v18 | v24 |
| Python minimum | 3.8 | 3.10 | 3.14 |
| Server Scripts | Enabled | Disabled default | Disabled default |
| Default sort | modified | modified | creation |
| patches.txt sections | Yes | Yes | Yes |
| Workspace sidebar | No | No | Yes |
| Separated modules | — | Event Streaming | Blog, Newsletter, EPS |
Reference Files
| File | Contents |
|---|---|
| examples.md | Complete upgrade workflow examples |
| anti-patterns.md | Common upgrade mistakes and fixes |
| breaking-changes.md | Detailed breaking changes per version |
| frappe-packages.md | Packages, fixtures, and moving customizations between sites |
What ships with it: 5 files
20.6 KB alongside SKILL.md
references/
- anti-patterns.md3.9 KB
- breaking-changes.md5.4 KB
- examples.md4.8 KB
- frappe-packages.md6.4 KB
- .gitkeep0 B