"Intelligent agent for validating ERPNext/Frappe code against best practices and common pitfalls. Use when reviewing generated code, checking for errors before deployment, or validating code quality. Triggers: review this code, check my script, validate before deployment, is this correct, find bugs, check for errors, will this work."
Resources
1Install
npx skillscat add openaec-foundation/erpnext-anthropic-claude-development-skill-package/erpnext-code-validator Install via the SkillsCat registry.
SKILL.md
ERPNext Code Validator Agent
This agent validates ERPNext/Frappe code against established patterns, common pitfalls, and version compatibility requirements.
Purpose: Catch errors BEFORE deployment, not after
When to Use This Agent
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ CODE VALIDATION TRIGGERS โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโค
โ โ
โ โบ Code has been generated and needs review โ
โ "Check this Server Script before I save it" โ
โ โโโ USE THIS AGENT โ
โ โ
โ โบ Code is causing errors โ
โ "Why isn't this working?" โ
โ โโโ USE THIS AGENT โ
โ โ
โ โบ Pre-deployment validation โ
โ "Is this production-ready?" โ
โ โโโ USE THIS AGENT โ
โ โ
โ โบ Code review for best practices โ
โ "Can this be improved?" โ
โ โโโ USE THIS AGENT โ
โ โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโValidation Workflow
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ CODE VALIDATOR WORKFLOW โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโค
โ โ
โ STEP 1: IDENTIFY CODE TYPE โ
โ โโโโโโโโโโโโโโโโโโโโโโโโโโ โ
โ โข Client Script (JavaScript) โ
โ โข Server Script (Python sandbox) โ
โ โข Controller (Python full) โ
โ โข hooks.py configuration โ
โ โข Jinja template โ
โ โข Whitelisted method โ
โ โ
โ STEP 2: RUN TYPE-SPECIFIC CHECKS โ
โ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ โ
โ โข Apply checklist for identified code type โ
โ โข Check syntax patterns โ
โ โข Verify API usage โ
โ โ
โ STEP 3: CHECK UNIVERSAL RULES โ
โ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ โ
โ โข Error handling present โ
โ โข User feedback appropriate โ
โ โข Security considerations โ
โ โข Performance implications โ
โ โ
โ STEP 4: VERIFY VERSION COMPATIBILITY โ
โ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ โ
โ โข v14/v15/v16 specific features โ
โ โข Deprecated patterns โ
โ โข Version-specific behaviors โ
โ โ
โ STEP 5: GENERATE VALIDATION REPORT โ
โ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ โ
โ โข Critical errors (must fix) โ
โ โข Warnings (should fix) โ
โ โข Suggestions (nice to have) โ
โ โข Corrected code (if errors found) โ
โ โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ See references/workflow.md for detailed validation steps.
Critical Checks by Code Type
Server Script Checks
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ โ ๏ธ SERVER SCRIPT CRITICAL CHECKS โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโค
โ โ
โ [FATAL] Import statements โ
โ โโโโโโโโโโโโโโโโโโโโโโโโโโโ โ
โ โ import json โ Use frappe.parse_json() โ
โ โ from frappe.utils import X โ Use frappe.utils.X() โ
โ โ import requests โ IMPOSSIBLE in Server Script โ
โ โ
โ [FATAL] Undefined variables โ
โ โโโโโโโโโโโโโโโโโโโโโโโโโโโโ โ
โ โ self.field โ Use doc.field โ
โ โ document.field โ Use doc.field โ
โ โ
โ [FATAL] Wrong event handling โ
โ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ โ
โ โ try/except for validation โ Just frappe.throw() โ
โ โ
โ [ERROR] Event name mismatch โ
โ โโโโโโโโโโโโโโโโโโโโโโโโโโโ โ
โ โ Event "Before Save" code in "After Save" script โ
โ โ
โ [WARNING] Missing validation โ
โ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ โ
โ โ ๏ธ No null/empty checks before operations โ
โ โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโClient Script Checks
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ CLIENT SCRIPT CRITICAL CHECKS โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโค
โ โ
โ [FATAL] Wrong API usage โ
โ โโโโโโโโโโโโโโโโโโโโโโโโโ โ
โ โ frappe.db.get_value() โ Server-side only! โ
โ โ frappe.get_doc() โ Server-side only! โ
โ โ frappe.call() for server data โ
โ โ
โ [FATAL] Missing async handling โ
โ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ โ
โ โ let result = frappe.call() โ Returns undefined โ
โ โ frappe.call({callback: fn}) โ Use callback โ
โ โ await frappe.call({async:false}) โ Or async/await โ
โ โ
โ [ERROR] Field refresh issues โ
โ โโโโโโโโโโโโโโโโโโโโโโโโโโโโ โ
โ โ frm.set_value() without refresh โ
โ โ frm.set_value() then frm.refresh_field() โ
โ โ
โ [WARNING] Form state checks โ
โ โโโโโโโโโโโโโโโโโโโโโโโโโโโ โ
โ โ ๏ธ Not checking frm.doc.__islocal for new docs โ
โ โ ๏ธ Not checking frm.doc.docstatus for submitted docs โ
โ โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโController Checks
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ CONTROLLER CRITICAL CHECKS โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโค
โ โ
โ [FATAL] Wrong lifecycle usage โ
โ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโ โ
โ โ Modifying self.field in on_update โ Changes NOT saved! โ
โ โ Use frappe.db.set_value() in on_update โ
โ โ
โ [FATAL] Missing super() call โ
โ โโโโโโโโโโโโโโโโโโโโโโโโโโโโ โ
โ โ def validate(self): pass โ Breaks parent validation โ
โ โ def validate(self): super().validate() โ
โ โ
โ [ERROR] Transaction assumptions โ
โ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ โ
โ โ Assuming rollback on error in on_update โ
โ (only validate and before_* roll back on error) โ
โ โ
โ [ERROR] Circular save โ
โ โโโโโโโโโโโโโโโโโโโโโโ โ
โ โ self.save() inside lifecycle hooks โ
โ โ doc.save() for same document in hooks โ
โ โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ See references/checklists.md for complete checklists.
Validation Report Format
## Code Validation Report
### Code Type: [Server Script / Client Script / Controller / etc.]
### Target DocType: [DocType name]
### Event/Trigger: [Event name]
---
### ๐ด CRITICAL ERRORS (Must Fix)
| Line | Issue | Fix |
|------|-------|-----|
| 3 | Import statement in Server Script | Use frappe.utils.X() directly |
### ๐ก WARNINGS (Should Fix)
| Line | Issue | Recommendation |
|------|-------|----------------|
| 12 | No null check before .lower() | Add: if value: value.lower() |
### ๐ต SUGGESTIONS (Nice to Have)
| Line | Suggestion |
|------|------------|
| 8 | Consider using frappe.db.get_value for single field |
---
### Corrected Code
```python
# [Corrected version with all critical errors fixed]Version Compatibility
| Version | Status |
|---|---|
| v14 | โ Compatible |
| v15 | โ Compatible |
| v16 | โ Compatible |
## Universal Validation Rules
These apply to ALL code types:
### Security Checks
| Check | Severity | Description |
|-------|----------|-------------|
| SQL Injection | CRITICAL | Raw user input in SQL queries |
| Permission bypass | CRITICAL | Missing permission checks before operations |
| XSS vulnerability | HIGH | Unescaped user input in HTML |
| Sensitive data exposure | HIGH | Logging passwords/tokens |
### Error Handling Checks
| Check | Severity | Description |
|-------|----------|-------------|
| Silent failures | HIGH | Catching exceptions without handling |
| Missing user feedback | MEDIUM | Errors not communicated to user |
| Generic error messages | LOW | "An error occurred" without details |
### Performance Checks
| Check | Severity | Description |
|-------|----------|-------------|
| Query in loop | HIGH | frappe.db.* inside for loop |
| Unbounded query | MEDIUM | SELECT without LIMIT |
| Unnecessary get_doc | LOW | get_doc when get_value suffices |
โ See [references/examples.md](references/examples.md) for validation examples.
## Version-Specific Validations
### v16 Features (Fail on v14/v15)
```python
# These ONLY work on v16+
extend_doctype_class = {} # hooks.py - v16 only
naming_rule = "UUID" # DocType - v16 only
pdf_renderer = "chrome" # Print Format - v16 onlyDeprecated Patterns (Warn)
# DEPRECATED - still works but should update
frappe.bean() # Use frappe.get_doc()
frappe.msgprint(raise_exception=True) # Use frappe.throw()
job_name parameter # Use job_id (v15+)Version-Specific Behaviors
| Behavior | v14 | v15/v16 |
|---|---|---|
| Scheduler tick | 240s | 60s |
| Background job dedup | job_name | job_id |
Quick Validation Commands
Server Script Quick Check
- โ Any
importstatements? โ FATAL - โ Any
self.references? โ FATAL (usedoc.) - โ Any
try/except? โ WARNING (usually wrong) - โ
Uses
frappe.throw()for validation errors? โ GOOD - โ
Uses
doc.fieldfor document access? โ GOOD
Client Script Quick Check
- โ Any
frappe.db.*calls? โ FATAL (server-side only) - โ Any
frappe.get_doc()calls? โ FATAL (server-side only) - โ
frappe.call()without callback? โ FATAL (async issue) - โ
Uses
frm.doc.fieldfor field access? โ GOOD - โ
Uses
frm.refresh_field()after changes? โ GOOD
Controller Quick Check
- โ Modifying
self.*inon_update? โ ERROR (won't save) - โ Missing
super().method()calls? โ WARNING - โ
self.save()in lifecycle hook? โ FATAL (circular) - โ Imports at top of file? โ GOOD (controllers allow imports)
- โ Error handling with try/except? โ GOOD (controllers allow this)
Integration with Other Skills
This validator uses knowledge from:
| Skill | What It Provides |
|---|---|
erpnext-syntax-* |
Correct syntax patterns |
erpnext-impl-* |
Correct implementation patterns |
erpnext-errors-* |
Error handling patterns |
erpnext-database |
Query patterns and pitfalls |
erpnext-permissions |
Permission check patterns |
erpnext-api-patterns |
API response patterns |
Validation Depth Levels
| Level | Checks | Use When |
|---|---|---|
| Quick | Fatal errors only | Initial scan |
| Standard | + Warnings | Pre-deployment |
| Deep | + Suggestions + Optimization | Production review |
Default: Standard level for most validations.