All insights

Agentforce

When validation rules block your Agentforce agent: the bypass pattern the agent user needs

The agent worked in the demo and fails on go-live with FIELD_CUSTOM_VALIDATION_EXCEPTION. The cause isn't the model. It's a validation rule written for a human filling a form, firing against a running user that never had the human's context. Here's how to exempt the agent user with a custom permission without weakening the rule for everyone else.

When validation rules block your Agentforce agent: the bypass pattern the agent user needs, article illustration

An agent closes a case cleanly in the demo. In production, the first attempt fails, and not because of the model. It reads FIELD_CUSTOM_VALIDATION_EXCEPTION: Reason code required before a case can be closed.

The agent picked the topic, chose the action, and assembled the update. Then a validation rule someone wrote for a human clicking Save rejected the write.

This is the most common way an Agentforce build stalls between demo and go-live, and it’s almost never a prompt problem. An agent action is Flow or Apex under the hood, so it runs against the same validation rules, required fields, and record-triggered flows as any other automation. Those rules were written for a person filling a form and reading the error.

The agent has neither the context that person had nor a human to read the message. So the fix isn’t a better instruction. It’s deciding, rule by rule, which ones the agent’s running user should be exempt from, and exempting it with a custom permission instead of loosening the rule for the whole org.

Get that call right and the agent stops failing on writes without opening a data-quality hole. Get it wrong in either direction and you either keep failing or let an agent write records your own rules would have caught.

First, know which user your agent is

You can’t exempt the agent until you know which user runs it, because the exemption is assigned to that user. Agentforce has two running-user models, and they aren’t the same person.

A customer-facing service agent runs as its own service user. When you create one, Salesforce provisions a user record with the Einstein Agent license and the Einstein Agent User profile. It also gets a permission set group, AgentforceServiceAgentUserPsg, which bundles the Agentforce Service Agent User, Data Cloud User, and Prompt Template User sets, plus a per-agent set named [Agent_Name]_Permissions.

Every record that agent reads or writes runs in that user’s security context.

An employee-facing agent, the assistant kind that helps a rep or an admin inside the org, runs as the logged-in user instead. Whatever the employee can do, the agent can do, and nothing more. I’ve written the full running-user model and least-privilege scoping separately, because it’s the layer most teams skip.

For the bypass problem the difference is everything. A service agent has one dedicated user you can safely exempt. An employee agent runs as a person on staff, so exempting “the agent” exempts that person in the normal UI too, which is usually not what you want. From here on I focus on the service-agent user, and I’ll flag the employee case where it changes the answer.

Why the rule fires against an agent and not a person

A validation rule doesn’t know who or what is saving the record. It evaluates a formula and blocks the write if the formula returns true.

The rule that says “Reason is required when Status is Closed” exists because a human, closing a case in a hurry, would otherwise skip it. When a person hits that error, they read it, pick a reason, and save again. The rule works because a person closes the loop.

The agent’s path breaks that in two ways. It often lacks the field the rule demands, because it never had the conversation that would have produced it. And when the write fails, there’s no human to read “Reason is required” and try again. The action returns an error to the reasoning engine, and depending on how you built it, the agent either apologizes to the customer or gives up on the task.

The two errors you’ll see most:

  • REQUIRED_FIELD_MISSING. The agent created or updated a record without a field a rule or the schema requires, because it didn’t hold the value a human would have typed.
  • FIELD_CUSTOM_VALIDATION_EXCEPTION. The agent’s write tripped a custom validation rule built for the UI, one its path never satisfies.

Both point at the same root cause: a rule that assumes a human’s context, firing against a user that doesn’t have it.

Don’t disable the rule. Exempt the user.

The wrong fix is the fast one. Deactivate the rule, or widen it until the agent slips through, and it stops protecting every human who saves that object. You wrote it for a reason. The agent shouldn’t be the reason you delete it.

The right fix makes the rule ignore one specific user, declaratively, with a custom permission. A validation rule formula can read whether the running user holds a custom permission through the $Permission global variable. Wrap the existing formula so it skips the check for anyone who holds a bypass permission:

AND(
  NOT( $Permission.Bypass_Case_Validations ),
  ISPICKVAL( Status, "Closed" ),
  ISBLANK( TEXT(Reason__c) )
)

The rule still fires for every human, exactly as before. It goes quiet only for a user who holds Bypass_Case_Validations. You assign that custom permission to the agent’s running user through a permission set, and for a service agent the natural home is the [Agent_Name]_Permissions set that already scopes it.

Custom permissions ride on permission sets and permission set groups, which buys you two things. You assign the bypass to exactly the users that need it. And permission set assignments can carry an expiration date, so a temporary exemption during a migration removes itself instead of living forever.

This is the discipline Salesforce recommends for any trusted-automation bypass. It beats checking a profile name or a hard-coded user ID in the formula, which breaks the moment someone clones the profile.

The goal is a rule that protects your data from people and steps aside for one governed agent, not a rule you turned off.

The same $Permission check works in a record-triggered flow. Gate the branch that enforces the rule behind a decision element that reads the custom permission, so the flow’s own validation and its side effects don’t fire for the agent user either. Whatever a Flow-based action triggers on save runs in the same running-user context, so if a record-triggered flow is what’s blocking the write, that’s where the gate goes.

Bypass the human-context rules, keep the data-quality ones

Here’s the judgment the custom permission forces on you, and it’s the part worth slowing down for. Not every rule should step aside for the agent. Split your rules into two piles.

Some rules encode human-workflow context. “Phone is required when Lead Source is Web.” “A close reason is required to close a case.” These assume a person had information the form should capture. An agent on a governed path may legitimately not have that field yet, and the rule is a landmine under it. These are the rules to exempt, or better, to satisfy.

Other rules encode data integrity that must hold no matter who writes. An amount can’t be negative. A close date can’t precede an open date. An email has to be well formed.

You don’t want the agent exempt from those. An agent writing at machine speed is exactly the actor you want them to catch, because a bad value it writes propagates through every downstream automation before a human ever sees it.

So the bypass permission is per-rule, by design. You add the NOT($Permission…) guard only to the rules in the first pile. The rules in the second pile keep firing against the agent, and that’s correct. An exemption that blankets every rule on the object is how an agent fills your org with records your own standards would have rejected.

Better than exempting: make the agent satisfy the rule

Exemption is the backstop, not the first move. For a required field the agent could reasonably obtain, the cleaner fix is to make the agent gather it before it writes, so the rule passes on its own.

That’s a design choice in the action and the topic. If closing a case needs a reason, give the agent an instruction and, where it helps, an input variable, so it asks for or infers the reason during the conversation and passes it into the update. The rule never fires because the record is actually complete. You keep the protection and you get a better interaction, because the agent collected what a good human agent would have.

Reserve the bypass for the rules the agent can’t satisfy at all: fields that depend on downstream systems, cross-object conditions that don’t apply to its path, or rules that exist purely to shape human data entry. For everything else, collecting the field is the cleaner fix than an exemption that lets the record through half-filled.

Return an error the agent can act on

There’s one more layer, and it’s the difference between an agent that recovers and one that dead-ends. When a write does fail, the action has to hand the reasoning engine something it can use.

A custom Apex action that lets a raw DmlException bubble up gives the model an opaque platform string. Catch it, and return a clear, structured message: what failed, and if possible what to do about it. “The case can’t be closed until a reason is provided; ask the customer for the reason and try again” is something the model can act on. System.DmlException: FIELD_CUSTOM_VALIDATION_EXCEPTION is not.

This is also where the boundary with governor limits shows up, because an action that fails under load looks the same from outside. An agent action runs inside the same transaction budget as any Apex, so a write that trips a limit and a write that trips a rule both surface as “the action failed.” Telling them apart is the production debugging that separates an agent that ships from one that stalls, and the field guide to Agentforce failures in production walks the error catalog layer by layer.

Build custom actions to be bulk-safe and to translate their own errors, the same way you would any Apex invocable action, and the agent stops failing silently.

The sequence I’d run before go-live

Take the objects your agent writes to. For each one, list the active validation rules and record-triggered flows, then sort them into the two piles: human-context and data-integrity.

For the human-context rules the agent can’t satisfy, add a NOT($Permission.<bypass>) guard and assign the permission to the agent’s running user through its permission set, time-boxed if the exemption is temporary. For the ones the agent could satisfy, change the topic and action so it collects the field instead. Leave the data-integrity rules alone. Then make every custom action catch its own DML errors and return a message the model can act on.

Do that and the “it worked in the demo and broke on go-live” failure mostly disappears, because the demo org had no rules firing and production does. The agent isn’t smarter afterward. It’s just no longer fighting rules that were never written with it in mind.

Understanding the basics

Why does my Agentforce agent fail with FIELD_CUSTOM_VALIDATION_EXCEPTION?

Because an agent action is Flow or Apex under the hood, so it’s subject to the same validation rules as any other write. The rule that’s firing was almost certainly written for a human filling a form, and the agent’s running user doesn’t have the field or context the rule assumes. The fix isn’t a prompt change. It’s deciding whether to exempt the agent’s user from that specific rule with a custom permission, or to make the agent collect the field so the rule passes.

How do I bypass a validation rule for the Agentforce agent user only?

Create a custom permission, then wrap the validation rule formula so it skips the check for anyone who holds it: AND(NOT($Permission.Your_Bypass), <your existing criteria>). Assign that custom permission to the agent’s running user through a permission set. For a service agent that’s the [Agent_Name]_Permissions set on the Einstein Agent User. The rule keeps firing for every human and goes quiet only for that one governed user.

Should I just deactivate the validation rule instead?

No. Deactivating it removes the protection for every human who saves that object, agent or not. Use a per-rule custom-permission guard so the rule still enforces for people and steps aside only for the agent, and only for the rules the agent cannot satisfy. Keep pure data-integrity rules firing against the agent, because a bad value it writes propagates through downstream automation faster than a human’s would.

Does the agent run as its own user or as the logged-in employee?

It depends on the agent type. A customer-facing service agent runs as its own service user, provisioned with the Einstein Agent license and Einstein Agent User profile. An employee-facing assistant runs as the logged-in user. That difference decides where you assign the bypass permission, and it’s why you can safely exempt a service agent’s dedicated user but should think twice before exempting a staff member from a rule they also hit in the UI.


Stuck between an agent that fails on every write and validation rules you can’t afford to lose? Talk to us about your Agentforce build. Getting the running-user permissions and the bypass boundaries right is exactly the unglamorous work that decides whether an agent survives go-live.

Keep reading

All insights