Use Agent Script to build agents that blend deterministic logic with the reasoning power of LLMs.
August ‘26
- You Must Fix New Agent Script Warnings:
-
Agent Script errors that were previously accepted now surface as warnings. If your
.agentfile has any of these warnings, you must fix them.Important If you don’t fix these warnings, you may not be able to save or commit your agent in a future release when the warnings are promoted to errors.- A
transitionstatement must have exactly one target. -
Search for these messages:
'transition' requires a target. Use 'transition to'.'transition' accepts a single 'to' target. Multiple 'to' clauses are not allowed.To fix, ensure your
transitionstatements contain a valid target.Incorrect (no target):
if @variables.data_collection_complete == False: transitionCorrect: (transition statement contains a target)
if @variables.data_collection_complete == False: transition to @topic.data_collectionIncorrect (one transition with two comma-separated targets):
if @variables.escalate == True: transition to @topic.order_help, to @topic.escalationCorrect (two transitions, each guarded by a condition):
if @variables.escalate == True: transition to @topic.escalation if @variables.escalate == False: transition to @topic.order_help - You can only set the value of a declared, mutable variable.
-
Search for these messages:
@utils.setVariables can only assign to declared variables.@utils.setVariables can only assign to mutable variables.To fix, use
@utils.setVariablesto set a variable's value. Declare the variable in thevariables:section, watch for typos in the variable name, and declare the variable as mutable.Incorrect (
user_namisn't declared — the actual variable isuser_name):variables: user_name: mutable string ... actions: set_user_info: @utils.setVariables with user_nam=...Correct:
variables: user_name: mutable string ... actions: set_user_info: @utils.setVariables with user_name=...Incorrect (
ContactIdis linked, sosetVariablescan't write to it):variables: ContactId: linked string ... actions: capture_contact: @utils.setVariables with ContactId=...Correct (declared as mutable, no typos ):
variables: ContactId: mutable string = "" ... actions: capture_contact: @utils.setVariables with ContactId=... - You can't chain statements after
@utils.setVariables. -
Search for this message:
Actions using @utils.setVariables cannot have transitions or follow-up actions.After
@utils.setVariablesruns and updates the variables, Agentforce returns control to reasoning. Directives chained after@utils.setVariablesdon't run. To fix, add the directive as a separate action.Incorrect (transition tacked onto the same action.):
actions: set_issue_details: @utils.setVariables with issue_type=... with issue_description=... transition to @topic.resolutionCorrect (runs the second action in
after_reasoning):reasoning: instructions: -> | Acknowledge the customer's frustration and express empathy. | Ask the customer to describe what type of issue they're having and the details of the issue. | Once you have both the issue type and description, use {!@actions.set_issue_details} to save them. actions: set_issue_details: @utils.setVariables description: "Capture the details of the user's issue or request." with issue_type = ... with issue_description = ... after_reasoning: if @variables.issue_type is not None: transition to @subagent.Resolution - Use
None(upper case) rather thannone(lower case) or null to check whether a variable is set. -
Search for this message:
'none' is not a valid value in AgentScript. Did you mean 'None' (capitalized) for an empty value?'null' is not a valid value in AgentScript. Use 'None' for an empty value or '""' for an empty string.To fix, use
None, with a capital N. Lowercasenoneandnullaren't valid.Incorrect: (Lower-case ‘none’)
actions: escalate_to_human: @utils.transition to @topic.escalation available when @variables.EndUserId != noneCorrect: (Upper-case “None”)
actions: escalate_to_human: @utils.transition to @topic.escalation available when @variables.EndUserId != NoneIncorrect (a variable’s value can’t be
null, and you can’t compare a variable againstnull):variables: customer_name: mutable string = null ... actions: ask_for_name: @actions.Prompt_For_Name available when @variables.customer_name == nullCorrect (use
Nonefor "no value"):variables: customer_name: mutable string = None ... actions: ask_for_name: @actions.Prompt_For_Name available when @variables.customer_name == None - Use
True/False(uppercase) rather thantrue/false(lowercase) to check boolean values. -
Search for these messages:
'true' is not a valid value in AgentScript. Did you mean 'True' (capitalized)?false' is not a valid value in AgentScript. Did you mean 'False' (capitalized)?Booleans in Agent Script are
TrueandFalse, capitalized. Lowercasetrueandfalsearen't valid.Incorrect: (Lower-case “true” and “false”)
variables: is_verified: mutable boolean = false ... actions: run_verified_flow: @actions.Do_Thing available when @variables.is_verified == trueCorrect: (Upper-case “true” and “false”)
variables: is_verified: mutable boolean = False ... actions: run_verified_flow: @actions.Do_Thing available when @variables.is_verified == True - Agent Script is a structured authoring language and only accepts valid syntax.
-
You can't include unrecognized text such as typos or unquoted strings, or use
@variableswhen the script is expecting@actions. Search for these messages, removing text enclosed with “<>” such as “<field>”:is not a defined value. Bare identifiers are not allowed here.is not a valid invocation target.Unknown field "<field>" in reasoning action "<action>".Fix typos, quote string literals in variable comparisons, and invoke actions rather than variables.
Incorrect (
pendingisn’t a variable or a string literal):actions: follow_up: @actions.Send_Reminder available when @variables.status == pendingCorrect (
"pending"is a string literal):actions: follow_up: @actions.Send_Reminder available when @variables.status == "pending"Incorrect (using a variable instead of an action):
actions: lookup: @variables.chosen_action description: "Do the thing"Correct (using an action where it belongs):
actions: lookup: @actions.Search_Products description: "Look up matching products"Incorrect (
descriptonis a typo,notesisn't a valid reasoning-action field):actions: lookup: @actions.Search_Products descripton: "Look up products" notes: "TODO wire this up"Correct:
actions: lookup: @actions.Search_Products description: "Look up products" label: "Product Search" - These blocks can’t be empty:
system:,variables:,connection:, andmodality:. -
If you have nothing to configure or declare in the block, omit the declaration from your Agent Script. Search for this message:
it has no content and will have no effect. Add configuration or remove the block.Incorrect (empty
system:block):system: config: developer_name: "MyAgent"Correct (either fill the block in, or delete it):
system: instructions: "You are a professional support assistant. Help users manage their requests efficiently." config: developer_name: "MyAgent" - Variable references in reasoning instructions must be enclosed
with
{!...}, for example{!variableName}. -
Incorrect —
orderNumberisn't enclosed with{!...}, so Agentforce treats it as regular text:reasoning: | Greet the user by their name customerName and confirm their order orderNumber.Correct — the reasoning instructions use
{!@variables.customerName}and{!@variables.orderNumber}, so the values are substituted at run time:reasoning: | Greet the user by their name {!@variables.customerName} and confirm their order {!@variables.orderNumber}.
- A
July ‘26
- Specify Mutually Exclusive Conditions with else if: Agent Script Reference: Conditional Expressions
- Use
else ifafter anifstatement to specify mutually exclusive conditions. Previously, Agent Script supported onlyifandelselogic.
- Set the Default Agent User in the New Access Block: Access Block
- Define your agent’s default user in the new
accessblock with thedefault_agent_userproperty. Thedefault_agent_userproperty is deprecated in theconfigblock.
June ‘26
- Delegate to Another Agentforce Agent with connected_subagent (Beta): Connected_Subagent Blocks
- Available the week of May 4. Use the
connected_subagentblock to define a connection to another Agentforce agent in your Salesforce org. Reference the connected subagent as a reasoning action, so that your agent can delegate requests to it.
- The ID Variable and Parameter Type Is Deprecated: Agent Script Reference: Variables and Agent Script Reference: Actions
- Use
stringinstead ofidto store Salesforce record IDs in variables and actions.
- Automatic Slot-Filling For Required Action Inputs: Agent Script Reference: Actions
- When a reference action has a required input that you don’t specify, the LLM provides the input from the user’s message. With automatic slot-filling, you don’t have to explicitly declare required inputs.
May ‘26
- Download Agent Script Documentation in Markdown: Download Agent Script Documentation
- Download Agent Script documentation as markdown files and feed them to your coding agent for accurate syntax and pattern references. If Salesforce Developers search isn’t finding what you need, use an IDE to search the downloaded Markdown files.
- End a Session with utils.end_session: utils.end_session
- End an agent conversation with
utils.end_session. Tell Agentforce to call this utility to terminate the session. For example, after completing a task or when the customer confirms they no longer need help.
- Create a Variable List of Objects: Agent Script Reference: Variables and Agent Script Pattern: Using List Variables
- Declare variables with type
list[object]. Previously, lists only supported primitive types. Lists of objects are useful when working with action outputs that return multiple records, such as order lines or search results.
- Clarification on None Checks for Variables: Agent Script Reference: Variables
- Available previously, we added examples of when to use
is None,is not None, and!= "". Check whether a variable has a value by usingis Noneoris not None. Useis Noneon any variable type. For string variables, you can also check for empty strings with!= "". On strings, combine both checks to handle all empty-value scenarios.
- Access Voice Call Properties with Linked Variables: Agent Script Reference: Variables
- Use the
@VoiceCallnamespace in linked variables to access properties of the current voice call. Previously, linked variables only supported@MessagingSessionand@MessagingEndUsersources. Now, you can build agents that reference the voice call ID directly in your agent script.
- Nest And and Or Operators with Parentheses: Agent Script Reference: Conditional Expressions and Agent Script Pattern: Using Conditionals
- Use parentheses
()to nestandandoroperators. Parentheses give you precise control over how conditions evaluate.
- Agent Script Functionality Changes:
- Agentforce now enforces these syntax violations. You may see new errors or
warnings reported in existing agents.
- You can’t have duplicate
withstatements. This example causes an error:reasoning: actions: get_info: @utils.setVariables # Error: Duplicate with first_name statement with first_name = "Alex" with first_name = "Sam" - You can’t have duplicate
set @variablesstatements. This example causes an error:reasoning: actions: lookup: @actions.OrderLookup with order_id = @variables.order_id # Error: Duplicate set @variables.status set @variables.status = @outputs.status set @variables.status = @outputs.updated_status - In an agent, every variable name must be unique. This example causes
an error:
variables: status: mutable string = "active" # Error: 'status' is already defined status: mutable boolean = True - In an action, every input and output name must be unique. This
example causes an error:
actions: OrderLookup: inputs: order_id: string # Error: 'order_id' is already defined in inputs order_id: string outputs: result: string # Error: 'result' is already defined in outputs result: string
- You can’t have duplicate