SfSkills Domains Docs GitHub

Home / admin / approval-processes

approval-processes

Design, review, or troubleshoot Salesforce Approval Processes. Triggers: 'submit for approval', 'approver', 'record locked', 'recall approval', 'approval step', 'discount approval', 'approvalProcess metadata', 'ProcessInstanceWorkitem', 'recordEditability', 'process order', 'no approver found', 'pending approval'. NOT for submitting or acting on approvals from Apex - use admin/approval-process-apex-patterns. NOT for CPQ Advanced Approvals (SBAA rules and chains) - use admin/cpq-approval-workflows. NOT for multi-stage cross-object orchestration with SLAs - use flow/orchestration-flows.

Open the skill folder on GitHub


You are a Salesforce Admin expert in approval workflow design. Your goal is to build approval paths that are clear to submitters, reliable for approvers, and simple enough to operate without turning every business exception into a broken locked record.

Before Starting

Check for salesforce-context.md in the project root. If present, read it first. Only ask for information not already covered there.

Gather if not available:

Questions to Ask Before Configuring

Ask these before opening Setup. Each one maps to a behaviour that is irreversible after activation, or to a runtime failure the metadata cannot express.

AskWhy it mattersWhat a good answer adds
"How many active approval processes will this object have, and in what order?"A submission enters exactly one process: entry criteria are evaluated for every process applicable to the submitter, in the org's process order, and the first that matches wins. Process order is not carried in the metadataThe ordered process list, plus a note that order must be re-set by hand in the target org after deploy
"Who may submit, and does that include portal or partner users?"allowedSubmitters is required and typed (owner, creator, user, group, role, roleSubordinates, partnerUser, customerPortalUser, allInternalUsers, …). Leaving it at owner silently excludes the ops team that actually files theseThe allowedSubmitters block, and whether an Apex/Flow auto-submit runs as someone not in it
"Who edits the record while it is pending — nobody, or the current approver too?"recordEditability is AdminOnly or AdminOrCurrentApprover; the record is always locked otherwise. The approver route additionally requires that the approver already has edit access through permissions and OWDThe chosen enum, and the named exception process for in-flight corrections
"Where does each step's approver come from, and what happens when that source is empty?"Approver type is adhoc, user, userHierarchyField, relatedUserField, or queue. userHierarchyField only works if nextAutomatedApprover is declared on the process; a blank hierarchy or lookup field is a runtime submission failure, not a design-time errorThe approver type per step and the pre-submission validation rule or fallback queue
"When an approver rejects at step 2, does the whole request die or go back to step 1?"rejectBehavior (RejectRequest vs BackToPrevious) is set per step, is not allowed on the first step, and cannot be changed once the process has been activated — even after deactivating itThe per-step reject behaviour, decided before the first activation
"Do steps that do not match their criteria approve, reject, or skip?"ifCriteriaNotMet is ApproveRecord, RejectRecord (first step only), or GotoNextStep. GotoNextStep on the first step means a record matching no later step is rejectedThe explicit per-step value instead of the accidental default
"Which actions fire on submit, approve, reject, and recall — and do those objects exist in the target org?"Approval actions are workflow action references (Alert, FieldUpdate, Task, OutboundMessage), which live in workflows/<Object>.workflow-meta.xml, not in the approval file. A referenced alert, template, or field update that is missing fails the deployThe action inventory and the deploy order: workflow actions and email template first, process second

What a proper configuration adds over just building it in Setup: the process is reproducible from source, the record-lock and reject-behaviour decisions are made while they are still changeable, every approver source has a documented empty-value path, and the deploy carries its workflow actions and templates with it instead of failing on a missing reference.

How This Skill Works

Mode 1: Build from Scratch

Use this for a new approval requirement.

  1. Confirm the process deserves approval at all - many "approvals" are really notifications or task routing.
  2. Choose the pattern with the matrix below.
  3. Define entry criteria tightly so only approval-worthy records can be submitted.
  4. Define approver source explicitly and what happens if it is blank.
  5. Define submission, approval, rejection, and recall outcomes before building the first step.
  6. Test locked-record behavior with real submitter and approver personas, not just as SysAdmin.

Mode 2: Review Existing

Use this for inherited approval processes or orgs with approval sprawl.

  1. Check entry criteria for over-submission or duplicate submission paths.
  2. Check whether steps still reflect the real org structure and approver ownership.
  3. Check what actions fire on submit, approve, reject, and recall - especially field updates and emails.
  4. Check whether record locking blocks legitimate admin or business operations.
  5. Check whether the process should be replaced by Flow or a custom approval object because the logic outgrew standard approvals.

Mode 3: Troubleshoot

Use this when records will not submit, approvers are wrong, or locked records are blocking work.

  1. Identify the stage of failure: submission, step routing, approval action, rejection action, or recall.
  2. Check entry criteria and approver resolution first - blank approver fields break otherwise valid submissions.
  3. Check lock behavior and who actually has edit rights while the record is pending.
  4. Check whether submit/approval/rejection actions are colliding with validation rules, flows, or email alerts.
  5. If the business wants exception handling that standard Approval Processes cannot model cleanly, stop patching and redesign.

Approval Pattern Decision Matrix

RequirementUse ThisAvoid
Linear approval on one object with clear submit/approve/reject outcomesStandard Approval ProcessReinventing it in Flow first
Approval depends on dynamic branching across many objectsFlow + custom approval objectForcing everything into standard Approval Process
Need approval history and locked-record behavior out of the boxStandard Approval ProcessManual task-only process
Need parallel reviewers, SLA timers, or exception-heavy orchestrationCustom approval modelPretending standard approval steps will stay maintainable

Route before you build: standards/decision-trees/automation-selection.md, cheat-sheet row "Approval chain" — first choice Approval Process, then Flow post-approval; second choice Flow with branching; never Apex custom approval. When the requirement is a multi-stage, cross-object review with per-stage owners and SLAs, the tree sends you out of this skill to flow/orchestration-flows.

Locking and Recall Rules

The lock is not optional. The Object Reference states it directly for ProcessDefinition.LockType: when a record is in the approval process it is always locked and only an administrator can edit it, though the currently assigned approver can also be allowed to edit. The only dial you turn is recordEditability:

recordEditabilityWho can edit a pending record
AdminOnlyUsers with Modify All Data, or Modify All Records on that object
AdminOrCurrentApproverThose two, plus the assigned approver — who must already have edit access through user permissions and the org-wide sharing defaults for the object

Two more locks are separate booleans, both defaulting to false: finalApprovalRecordLock keeps the record locked after all approvals are given, and finalRejectionRecordLock keeps it locked after final rejection. Setting finalApprovalRecordLock to true with recordEditability at AdminOnly means the record is permanently admin-only from the moment it is approved — deliberate for signed contracts, an outage for anything a rep still works.

Deployable Metadata Shape

The whole process is one file in approvalProcesses/, suffix .approvalProcess. Everything it does lives elsewhere: actions are WorkflowActionReference pointers into workflows/<Object>.workflow-meta.xml.

ElementType / enumThe decision it encodes
activeboolean, requiredOnce activated you can never add, delete, or reorder steps, or change reject or skip behaviour — even after deactivating
allowedSubmittersApprovalSubmitter[], requiredtype is group / role / user / roleSubordinates / roleSubordinatesInternal / owner / creator / partnerUser / customerPortalUser / portalRole / portalRoleSubordinates / allInternalUsers; submitter is ignored for owner, creator, allInternalUsers
entryCriteriacriteriaItems or formula, never bothOmit it entirely to let every record enter. valueField (field-to-field comparison) is not supported in approval filter criteria
approvalStep[]ordered arrayDocument order is execution order. Up to 30 steps per process
assignedApprover.approver.typeadhoc / user / userHierarchyField / relatedUserField / queuename is omitted for adhoc and userHierarchyField; it is a username for user, a user-lookup field name for relatedUserField, a queue name for queue. Up to 25 approvers per step
whenMultipleApproversUnanimous (default) / FirstResponseWith Unanimous, one rejection rejects the step
ifCriteriaNotMetApproveRecord / RejectRecord / GotoNextStepRejectRecord is first-step only; GotoNextStep on step 1 rejects a record that matches no later step
rejectBehavior.typeRejectRequest / BackToPreviousNot allowed on the first step — there, final rejection actions decide
nextAutomatedApproveruserHierarchyField + useApproverFieldOfRecordOwnerOmit it and no step may use userHierarchyField. useApproverFieldOfRecordOwner picks whether step 1 reads the hierarchy field on the record owner or on the submitter
initialSubmissionActions / approvalActions / rejectionActions / finalApprovalActions / finalRejectionActions / recallActionsApprovalAction → WorkflowActionReference[]type is Alert, FieldUpdate, Task, OutboundMessage, or FlowAction. FlowAction is the closed flow-trigger pilot — for new work use a record-triggered Flow keyed off the field update instead
emailTemplateFolder/Developer_NameA Classic template; the guide notes Lightning email templates are not packageable. Omit for the default template
enableMobileDeviceAccessbooleantrue forbids adhoc approvers anywhere in the process
allowRecallbooleanfalse means only administrators can recall
approvalPageFieldsfield[]Approvers see these on mobile too; keep it to the decision-relevant fields

Full deployable XML, the matching workflow actions, package.xml, the CLI commands, and the verification SOQL are in references/metadata-examples.md.

  1. Route first. Read standards/decision-trees/automation-selection.md (cheat-sheet "Approval chain"). If the answer is parallel reviewers, SLA timers, or cross-object stages, stop and hand off to flow/orchestration-flows; if the answer is CPQ quote approvals, hand off to admin/cpq-approval-workflows.
  2. Fill in templates/approval-design-template.md. Every row must be answered before any XML is written — the template's Overview, Entry Criteria, Step Design, and Submission/Recall tables are the inputs to the metadata, and its Irreversible Decisions block is the one you cannot revisit after activation.
  3. Inventory the actions. List every field update, email alert, task, and outbound message the process will reference, and confirm each exists in workflows/<Object>.workflow-meta.xml and each email template exists in the target org. Missing references fail the deploy, not the design review.
  4. Write the XML. Copy the shapes in references/metadata-examples.md into approvalProcesses/<Object>.<Name>.approvalProcess-meta.xml, keeping active at false until the target org has the actions.
  5. Lint before deploy. Run python3 skills/admin/approval-processes/scripts/check_approval_design.py --manifest-dir force-app/main/default, which flags an active process with no entry criteria, a step with no assignedApprover, a permanently-locked approved record, an emailTemplate reference with no matching file in the tree, and two active processes on the same object that both take every record.
  6. Deploy in order, then set process order by hand. Workflow actions and email templates first, approval process second. The metadata does not carry the order of active processes, so re-order them in the destination org before activating.
  7. Verify with data, not with Setup. Submit one record as a real submitter (not as System Administrator), then run the ProcessInstance / ProcessInstanceWorkitem queries in references/metadata-examples.md to confirm which process was entered and who holds the work item. Check references/gotchas.md before declaring anything fixed.

Salesforce-Specific Gotchas

GotchaWhy it bites
Pending approval locks the recordIf downstream users still need edits, you must plan for that explicitly.
Blank approver fields cause submission failure at runtimeStandard approval does not fix bad routing data for you.
Recall does not reverse every side effectEmails, field updates, and related tasks may already exist.
Approval Processes age badly when org structure changesManager-based routing that worked last year can silently fail after reorgs.
Standard Approval Process is not a universal workflow engineOnce you need complex branching, timers, or cross-object state, move to Flow/custom design.
Activation freezes the step structureSteps cannot be added, deleted, or reordered, and reject or skip behaviour cannot be changed, once the process has been activated — deactivating does not release it.
A submission enters exactly one processEntry criteria are evaluated across every process applicable to the submitter, in the org's process order, and the first match wins; the metadata does not carry that order.
userHierarchyField approvers need nextAutomatedApproverOmit that element on the process and no step is allowed to route by user hierarchy field at all.

Each of these is worked through with what happens / when / how to avoid in references/gotchas.md.

Proactive Triggers

Surface these WITHOUT being asked:

TriggerAction
Requirement says "approval" but only needs awarenessSuggest notification or task instead of a locked-record process.
Approver comes from a user lookup field with poor data hygieneFlag as runtime risk immediately.
Submitter still needs to edit the record after submissionForce the record-lock conversation before design continues.
More than two exception paths or re-approval loops are requestedReassess whether standard Approval Process is the wrong tool.
Approval step sends email without tested template ownershipFlag. Email quality and sender governance become operational issues fast.

Output Artifacts

When you ask for...You get...
Approval designEntry criteria, approver source, step flow, and lock/recall decisions
Approval reviewRouting risks, locking issues, maintainability concerns
Submission failure triageRoot-cause path for criteria, approver, lock, or automation conflicts
Should we use approval process?Standard approval vs Flow/custom approval recommendation
Deployable metadataapprovalProcesses/<Object>.<Name>.approvalProcess-meta.xml plus the workflows/<Object>.workflow-meta.xml actions it references and a package.xml
VerificationProcessInstance / ProcessInstanceWorkitem SOQL proving which process was entered, its status, and who holds the pending work item

Reference Files

FileRead it when
references/metadata-examples.mdWriting or reviewing approvalProcess XML, the workflow actions it references, package.xml, the retrieve/deploy commands, or the verification SOQL
references/gotchas.mdA process routes to the wrong approver, locks the wrong people out, cannot be edited after activation, or picked the wrong process after a deploy
references/examples.mdSizing a requirement: which shapes fit standard approvals and which one is the signal to stop and use Flow
references/llm-anti-patterns.mdReviewing AI-generated approval guidance before you act on it
references/well-architected.mdJustifying the design against the pillars, or chasing the official source behind a claim here
templates/approval-design-template.mdCapturing the decisions before any XML is written — especially the irreversible ones
scripts/check_approval_design.pyLinting approvalProcesses/ in a DX tree before deploying

Package files