$npx -y skills add Impertio-Studio/Frappe_Claude_Skill_Package --skill frappe-agent-validatorUse when reviewing or validating Frappe/ERPNext code against best practices and common pitfalls. Checks generated code before deployment, validates against all 61 frappe-* skills, catches v16 patterns (extend_doctype_class, type annotations), validates ops patterns (bench command
| 1 | # Frappe Code Validator Agent |
| 2 | |
| 3 | Validates Frappe/ERPNext code against the complete 61-skill knowledge base, catching errors BEFORE deployment. |
| 4 | |
| 5 | **Purpose**: Catch errors before deployment, not after |
| 6 | |
| 7 | ## When to Use This Agent |
| 8 | |
| 9 | ``` |
| 10 | CODE VALIDATION TRIGGERS |
| 11 | | |
| 12 | +-- Code has been generated and needs review |
| 13 | | "Check this Server Script before I save it" |
| 14 | | --> USE THIS AGENT |
| 15 | | |
| 16 | +-- Code is causing errors |
| 17 | | "Why isn't this working?" |
| 18 | | --> USE THIS AGENT |
| 19 | | |
| 20 | +-- Pre-deployment validation |
| 21 | | "Is this production-ready?" |
| 22 | | --> USE THIS AGENT |
| 23 | | |
| 24 | +-- Code review for best practices |
| 25 | | "Can this be improved?" |
| 26 | | --> USE THIS AGENT |
| 27 | | |
| 28 | +-- Ops/deployment validation |
| 29 | | "Is my bench setup correct?" |
| 30 | | --> USE THIS AGENT |
| 31 | ``` |
| 32 | |
| 33 | ## Validation Workflow |
| 34 | |
| 35 | ``` |
| 36 | STEP 1: IDENTIFY CODE TYPE |
| 37 | Client Script | Server Script | Controller | hooks.py | |
| 38 | Jinja | Whitelisted | Bench/Ops | DocType JSON |
| 39 | |
| 40 | STEP 2: RUN TYPE-SPECIFIC CHECKS |
| 41 | Apply checklist for identified code type |
| 42 | |
| 43 | STEP 3: CHECK UNIVERSAL RULES |
| 44 | Error handling | Security | Performance | User feedback |
| 45 | |
| 46 | STEP 4: VERIFY VERSION COMPATIBILITY |
| 47 | v14/v15/v16 features | Deprecated patterns |
| 48 | |
| 49 | STEP 5: VALIDATE AGAINST SKILL CATALOG |
| 50 | Cross-reference with relevant frappe-* skills |
| 51 | |
| 52 | STEP 6: GENERATE VALIDATION REPORT |
| 53 | Critical errors | Warnings | Suggestions | Corrected code |
| 54 | ``` |
| 55 | |
| 56 | See [references/workflow.md](references/workflow.md) for detailed steps. |
| 57 | |
| 58 | ## Critical Checks by Code Type |
| 59 | |
| 60 | ### Server Script Checks |
| 61 | |
| 62 | | Check | Severity | Pattern | Fix | |
| 63 | |-------|----------|---------|-----| |
| 64 | | Import statements | FATAL | `import X` or `from X import Y` | Use `frappe.utils.X()` directly | |
| 65 | | Wrong doc variable | FATAL | `self.field` or `document.field` | Use `doc.field` | |
| 66 | | Wrong event for purpose | ERROR | Validation code in on_update | Move to validate event | |
| 67 | | try/except blocks | WARNING | `try: ... except:` | Use `frappe.throw()` for validation | |
| 68 | | No null checks | WARNING | `doc.field.lower()` | Add `if doc.field:` guard | |
| 69 | |
| 70 | ### Client Script Checks |
| 71 | |
| 72 | | Check | Severity | Pattern | Fix | |
| 73 | |-------|----------|---------|-----| |
| 74 | | Server-side API calls | FATAL | `frappe.db.get_value()` | Use `frappe.call()` | |
| 75 | | Missing async handling | FATAL | `let x = frappe.call()` | Use callback or async/await | |
| 76 | | No refresh after set_value | ERROR | `frm.set_value()` alone | Add `frm.refresh_field()` | |
| 77 | | Using cur_frm | WARNING | `cur_frm.doc.field` | Use `frm` parameter | |
| 78 | | No form state check | WARNING | Missing `__islocal`/`docstatus` | Add state guards | |
| 79 | |
| 80 | ### Controller Checks |
| 81 | |
| 82 | | Check | Severity | Pattern | Fix | |
| 83 | |-------|----------|---------|-----| |
| 84 | | self.* in on_update | FATAL | `self.field = X` in on_update | Use `self.db_set()` | |
| 85 | | Circular save | FATAL | `self.save()` in lifecycle hook | Remove self.save() | |
| 86 | | Missing super() | ERROR | Override without super() | Add `super().method()` | |
| 87 | | v16 extend_doctype_class | ERROR | Missing super() in mixin | ALWAYS call super() first | |
| 88 | | No type annotations | SUGGESTION | Missing type hints (v16) | Add type annotations | |
| 89 | |
| 90 | ### hooks.py Checks |
| 91 | |
| 92 | | Check | Severity | Pattern | Fix | |
| 93 | |-------|----------|---------|-----| |
| 94 | | Invalid Python syntax | FATAL | Syntax errors | Fix dict/list structure | |
| 95 | | Wrong event names | FATAL | Typo in event name | Use correct event names | |
| 96 | | Invalid function paths | FATAL | Wrong dotted path | Verify path exists | |
| 97 | | v16-only hooks on v14/v15 | ERROR | `extend_doctype_class` | Use `doc_events` instead | |
| 98 | | Missing required_apps | WARNING | No dependency declaration | Add all dependencies | |
| 99 | |
| 100 | ### Ops/Bench Checks |
| 101 | |
| 102 | | Check | Severity | Pattern | Fix | |
| 103 | |-------|----------|---------|-----| |
| 104 | | No migrate after hooks | FATAL | hooks.py changed, no migrate | Run `bench migrate` | |
| 105 | | Wrong bench command syntax | ERROR | Incorrect CLI args | Check `frappe-ops-bench` | |
| 106 | | Missing backup before upgrade | ERROR | Upgrade without backup | ALWAYS backup first | |
| 107 | | Production without supervisor | WARNING | No process manager | Use supervisor/systemd | |
| 108 | | No SSL in production | WARNING | HTTP-only deployment | Configure SSL/TLS | |
| 109 | |
| 110 | ### DocType JSON Checks |
| 111 | |
| 112 | | Check | Severity | Pattern | Fix | |
| 113 | |-------|----------|---------|-----| |
| 114 | | Missing mandatory fields | ERROR | No primary identifier | Add name or autoname | |
| 115 | | Duplicate fieldnames | FATAL | Same fieldname t |