before-vs-after-trigger
Skill1 starsChanged 7 months agoMITView on GitHub
Decide whether a piece of trigger logic belongs in `before insert/update` or `after insert/update`. Asks 4–5 quick questions, then recommends with rationale.
In this repository53 other files it gives its agents.
- templates/CLAUDE.mdCLAUDE.md
- adrSkill
- agent-deploySkill
- agent-discoverSkill
- agent-eval-trendSkill
- agent-exchange-listSkill
- agent-specSkill
- agent-testSkill
- agent-vs-flow-vs-apexSkill
- code-reviewSkill
- complexitySkill
- coverage-trendSkill
- dead-codeSkill
- dependency-graphSkill
- deploySkill
- destructive-changesSkill
- diff-deploySkill
- erdSkill
- field-impactSkill
- flaky-test-finderSkill
- flow-auditSkill
- flow-vs-apexSkill
- fls-auditSkill
- gateway-configSkill
- generate-docsSkill
- limit-usageSkill
- lwc-vs-reactSkill
- mcp-tool-vs-restSkill
- notifySkill
- onboardSkill
- org-diffSkill
- org-exploreSkill
- package-versionSkill
- pattern-packSkill
- perf-reviewSkill
- permset-auditSkill
- pr-prepareSkill
- queueable-vs-batchSkill
- quick-deploySkill
- react-initSkill
- release-notesSkill
- scratch-orgSkill
- security-scanSkill
- sequence-diagramSkill
- sf-initSkill
- sharing-reviewSkill
- slack-agentSkill
- soql-analyzerSkill
- test-coverageSkill
- test-dataSkill
- test-planSkill
- trust-evalSkill
- trust-layer-auditSkill
The file
We split this skill into the rules it gives an agent
2 rules. About 0 are common, 0 are distinctive, and 2 are very specific to this project.
≈0
Common · estimate
Many files like this have a rule of this kind.
≈0
Distinctive · estimate
This author's own choices. Worth a look.
2
Very specific
Tied to their project's names, files or tools. Probably skip.
- Common
- Distinctive
- Very specific
- Very specific: line 95
before inserthas noIdand nooldMap: Don't recommend it for anything that needs either - Very specific: line 96
addErroronly works inbefore: If the goal is to reject, before is the only choice
≈ “Common” is an estimate: at least 1 in 5 of the 350,495 skill files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.
Files
You are helping the user pick the right trigger phase. Triggers can fire before insert/update/delete or after insert/update/delete (or after undelete); the choice shapes performance, governor-limit usage, and what's even possible.
Decision questions
- What does the logic do? Set field values on the record itself / create or update other records / send notifications / cascade DML / call out to external?
- Does it need the record's
Id? (Available onlyafter insert, notbefore insert) - Does it need the old value of a field? (
Trigger.oldMapavailable inbefore updateandafter update) - Does it need to fail/abort the operation? (
addErroravailable inbeforeonly —aftercan throw but you've already done DML elsewhere) - Does it touch external systems? (Callouts forbidden in triggers; queue from
after)
Decision tree
Set field values on the same record being saved
→ before insert / before update — modify Trigger.new directly; no extra DML
Reject / abort the save with a user-friendly error
→ before insert / before update — addError on the record
Cascade-create child records (Order_Item__c when Order__c is inserted)
→ after insert — child records need parent's Id
Update related parent / sibling records (set Account.Total when Opportunity inserts)
→ after insert / after update — DML on related records
Recompute a roll-up that lives in another object
→ after insert / after update / after delete — DML on the other object
Publish a Platform Event
→ after insert / after update — publish-after-commit ensures event matches persisted state
Enqueue a Queueable for async work (callouts, heavy processing)
→ after insert / after update — record is committed; the queueable can rely on Id and current state
Validation that depends on other records (cross-record check)
→ before insert / before update — fetch related records and addError as neededOutput
# Trigger Phase Choice
## Description
Cascade-create three Order_Item__c records when an Order__c with Status__c='AutoLine' is inserted
## Answers
- Logic: create child records
- Needs Id: yes (Order__c.Id is the FK on Order_Item__c)
- Needs oldMap: no
- Aborts save: no
- External call: no
## Recommendation: **after insert**
### Why
- Child records reference `Order__c.Id`, which only exists after the parent is persisted (`after insert`)
- No abort path — pure cascade
- DML cost: 1 INSERT per Order__c trigger context (200 rows = 1 bulk insert), within governor limits
### Patterns referenced
- SF-7 (Trigger Handler Framework) — `afterInsert()` method on the handler
### Boilerplate
```apex
public class OrderTriggerHandler implements ITriggerHandler {
public void afterInsert() {
List<Order_Item__c> items = new List<Order_Item__c>();
for (Order__c o : (List<Order__c>) Trigger.new) {
if (o.Status__c == 'AutoLine') {
items.add(new Order_Item__c(Order__c = o.Id, Quantity__c = 1));
items.add(new Order_Item__c(Order__c = o.Id, Quantity__c = 2));
items.add(new Order_Item__c(Order__c = o.Id, Quantity__c = 3));
}
}
if (!items.isEmpty()) insert as user items;
}
// other ITriggerHandler stubs return without action
}Alternatives
before insertwould not work — you can't setOrder_Item__c.Order__c = new Order__c().Idbefore the parent has an Id
## Rules
- **`before` for self-record changes; `after` for cross-record DML.** This single rule covers ~90% of cases
- **`before insert` has no `Id` and no `oldMap`.** Don't recommend it for anything that needs either
- **`addError` only works in `before`.** If the goal is to reject, `before` is the only choice
- **Don't put callouts in triggers.** Trigger phase is irrelevant — callouts inside a trigger throw `CalloutException`. Always queue themDoes it work?
Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.
No reviews yet
People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.
- It worked
- Partly
- It didn't
Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.
Your trail
Files you open will collect here, so you can find them again.
Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.
Now do this for your own.
Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.

