Add custom field
Skill prilk-consulting/frappe-agent-kit/skills/add-custom-field
Production-grade Frappe Framework & ERPNext skills, agents, and scaffolding commands for Claude Code
npx -y skills add prilk-consulting/frappe-agent-kit --skill add-custom-fieldAssembled from the repository path, not quoted from the project. Check it against their README if it does not work.
One thing to look at
- 0 stars0 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.
What its author says it does
Copied from the file, not written here
Step-by-step workflow to add a custom field to another app's DocType (e.g. Customer, Sales Invoice) from your own app, idempotently via install.py. Use when the user asks to add a field to a standard/ERPNext doctype, extend Customer with X, or store extra data on an existing DocType.
SKILL.md
3.7 KB, 819 tokens by cl100k_base, as published. Nobody here has run it
Add a Custom Field to Another App's DocType
For adding fields to a DocType your own app owns, just edit its JSON (see frappe-dev) — this workflow is for extending DocTypes owned by frappe/erpnext/another app, where editing their JSON is forbidden.
Usage
Use this skill when:
- "Add a field to Customer / Sales Invoice / Item / …"
- Your app needs to store its own data on a standard DocType
- Reviewing whether a custom field was added the upgrade-safe way
Steps
1. Check it doesn't already exist — and whether a field is even needed
bench --site <site> execute frappe.client.get_list --kwargs "{'doctype':'Custom Field','filters':{'dt':'Customer'},'fields':['fieldname','label','insert_after','module']}"
- Field already there (maybe under another app)? STOP — never manage another app's custom fields.
- Linking records M:N (contact↔customer, address↔supplier)? Use
Contact.links/ Dynamic Link instead of a new field. - Several related fields? Consider a separate DocType linked back, not five custom fields.
2. Define it in your app's install.py
Add to the existing get_custom_fields() dict (create the install.py wiring if the app lacks it — frappe-dev skill has the full pattern):
def get_custom_fields():
return {
"Customer": [
{
"fieldname": "<app_prefix>_<name>", # prefix avoids collisions: "myapp_risk_score"
"label": "<Label>",
"fieldtype": "<Type>", # Link/Select/Check/Currency > Data
"insert_after": "<existing_fieldname>", # pick from the target's JSON, not from memory
"module": "<Your Module>", # marks ownership
# "options": "...", "read_only": 1, "depends_on": "eval:...", as needed
},
],
}
Conventions:
- Prefix the fieldname with your app name —
dt + fieldnamemust be unique site-wide, and unprefixed names collide with future framework fields. insert_after: open the target DocType's JSON in apps/frappe or apps/erpnext and choose a real neighbor; a wrong value silently appends to the end.- Set
moduleso the field is attributable (and exportable by module filter) to your app.
3. Apply without waiting for a migrate
bench --site <site> execute <app>.install.after_migrate
(Works because after_migrate calls create_custom_fields(get_custom_fields()) — idempotent, safe to run repeatedly.)
4. Verify
bench --site <site> execute frappe.get_meta --args "['Customer']" | grep -o '<app_prefix>_<name>'
Then open the form in the desk: field appears in the right place, behaves per its flags. If code reads the field, access it with doc.get("<fieldname>") — attribute access raises on sites where the app isn't installed yet.
5. If the field needs data on existing records
Backfill via a patch (frappe-upgrade skill) — never in after_migrate (it would re-run the backfill logic on every migrate).
Rules
- One owner per field: your app creates, reads, writes, and (on uninstall) removes ONLY its own custom fields.
- Both
after_installANDafter_migratemust callcreate_custom_fields— fields must survive fresh installs and migrations alike. - Property changes to a standard field (hide it, relabel it) use a Property Setter through the same install.py pattern — not editing the other app's JSON.
What ships with it
Read from the repository
Just SKILL.md. No reference files, no scripts.