developing-agentforce: Employee Agent host-context variables produce silent runtime failure (examples.md wrong, visibility: undocumented, current* reserved names not mentioned)
Target repo: SalesforceAIResearch/agentforce-adlc
Skill: developing-agentforce
Primary files:
skills/developing-agentforce/references/examples.md — "Minimal Employee Agent" section (lines 63–182)
skills/developing-agentforce/references/agent-script-core-language.md — Core Language reference (no coverage of visibility: or host-context vars)
skills/developing-agentforce/SKILL.md — Syntax Quick Reference (no coverage of either)
skills/developing-agentforce/references/production-gotchas.md — no entry for silent host-context failure
Summary
The skill's "Minimal Employee Agent" example and surrounding references diverge from what the Salesforce Agent Builder UI actually emits when creating a new AgentforceEmployeeAgent. The divergence isn't cosmetic — it causes a silent runtime failure that cannot be caught by any tool in the skill's workflow:
- The agent compiles (
sf agent validate authoring-bundle returns success: true)
- The agent publishes cleanly
- The agent previews correctly for any utterance that doesn't rely on host-surface context
- But when embedded on a Lightning Record Page, variables that were supposed to receive the current record context are never populated by the host — because the skill doesn't mention the three things required to wire them up correctly: the reserved variable names, the
visibility: attribute, and the External contract with the host surface.
Concretely, three distinct errors in the skill's current content combine to produce the failure:
- Error C1 —
examples.md (line 181) asserts EndUserId / RoutableId / ContactId / EndUserLanguage are "service-agent-only." This is factually incorrect; the UI emits them on employee agents too.
- Error C2 — the
current* host-context variables (currentRecordId, currentObjectApiName, currentPageType, currentAppName) are the mechanism by which an embedded employee agent receives Lightning Record Page context. They are never mentioned anywhere in the skill — not in examples.md, not in agent-script-core-language.md, not in SKILL.md, not in agent-design-and-spec-creation.md.
- Error C3 — the
visibility: attribute ("External" / "Internal" / omitted) on variable declarations is undocumented. The Core Language reference and the Syntax Quick Reference never mention it. But visibility: "External" is what opts a variable in to being populated by the host surface. Without it, the host never writes — silently.
Concrete failure case: an author building an employee agent that answers "what's the billing address for this account?" will, following the skill literally, declare currentRecordId: mutable string = "" with no visibility: attribute. It compiles, validates, previews, publishes. Embedded on an Account record page, @variables.currentRecordId is always empty. The instruction if @variables.currentRecordId is not empty becomes dead code. The agent asks "which account?" even though the user is clearly on one. No validator warning fires.
I hit this while building a single-topic employee agent for Account billing address lookups on 2026-04-25. All three errors below are documented against the current state of the skill files on main, and all three show up in .agent output emitted by the Salesforce UI that contradicts the skill.
Evidence
Evidence — UI-generated variable blocks (copied directly from Agent Builder output)
Service Agent (UI default, no manual edits):
variables:
authenticationKey: mutable string
description: "Stores the authentication key that's used to generate the verification code."
visibility: "Internal"
customerId: mutable string
description: "Stores the Salesforce user ID or contact ID."
visibility: "Internal"
customerType: mutable string
description: "Stores the customer ID type, whether it's a Salesforce user or a contact."
visibility: "Internal"
isVerified: mutable boolean = False
label: "isVerified"
description: "Stores a boolean value that indicates whether the customer code is verified."
visibility: "Internal"
EndUserId: linked string
source: @MessagingSession.MessagingEndUserId
description: "This variable may also be referred to as MessagingEndUser Id"
RoutableId: linked string
source: @MessagingSession.Id
description: "This variable may also be referred to as MessagingSession Id"
ContactId: linked string
source: @MessagingEndUser.ContactId
description: "This variable may also be referred to as MessagingEndUser ContactId"
EndUserLanguage: linked string
source: @MessagingSession.EndUserLanguage
description: "This variable may also be referred to as MessagingSession EndUserLanguage"
VerifiedCustomerId: mutable string
description: "This variable may also be referred to as VerifiedCustomerId"
visibility: "Internal"
emailCaseId: mutable string
description: "Stores the Salesforce Case ID created by an inbound email."
visibility: "External"
endUserEmail: mutable string
description: "Stores email address of the end user who sent the inbound email."
visibility: "External"
endUserContactId: mutable string
description: "Stores the Salesforce Contact ID associated with the end user who sent the inbound email."
visibility: "External"
Employee Agent (UI default, no manual edits):
variables:
EndUserId: linked string
source: @MessagingSession.MessagingEndUserId
description: "This variable may also be referred to as MessagingEndUser Id"
visibility: "External"
RoutableId: linked string
source: @MessagingSession.Id
description: "This variable may also be referred to as MessagingSession Id"
visibility: "External"
ContactId: linked string
source: @MessagingEndUser.ContactId
description: "This variable may also be referred to as MessagingEndUser ContactId"
visibility: "External"
EndUserLanguage: linked string
source: @MessagingSession.EndUserLanguage
description: "This variable may also be referred to as MessagingSession EndUserLanguage"
visibility: "External"
currentAppName: mutable string
description: "Salesforce Application Name"
visibility: "External"
currentObjectApiName: mutable string
description: "The API name of the current Salesforce object"
visibility: "External"
currentPageType: mutable string
description: "Page type (record, list, home)"
visibility: "External"
currentRecordId: mutable string
description: "The Salesforce ID of the current record"
visibility: "External"
VerifiedCustomerId: mutable string
description: "This variable may also be referred to as VerifiedCustomerId"
visibility: "Internal"
Side-by-side (what the UI makes unambiguous):
| Variable |
Service UI default |
Employee UI default |
authenticationKey / customerId / customerType / isVerified |
✅ Internal |
— |
EndUserId / RoutableId / ContactId / EndUserLanguage (linked) |
✅ (no visibility: attr) |
✅ External |
VerifiedCustomerId |
✅ Internal |
✅ Internal |
emailCaseId / endUserEmail / endUserContactId |
✅ External |
— |
currentAppName / currentObjectApiName / currentPageType / currentRecordId |
— |
✅ External |
Four observations:
@MessagingSession linked variables appear on both agent types.
- The
visibility: attribute has three observable states: "External", "Internal", and omitted. The service-agent UI output emits MessagingSession linked vars with no visibility: at all; the employee-agent UI output emits the same names with visibility: "External". The semantic difference is undocumented.
- The
current* host-context variables only appear on employee agents. They are the mechanism for Lightning Record Page context.
- Service agents have two additional variable groups the skill never mentions — a verification flow quartet (
authenticationKey/customerId/customerType/isVerified) and an email-to-case trio (emailCaseId/endUserEmail/endUserContactId).
Error C1 — examples.md wrongly excludes @MessagingSession linked variables from employee agents
skills/developing-agentforce/references/examples.md, line 85 (inside config: of Minimal Employee Agent):
# NOTE: No default_agent_user — employee agents run as the logged-in user.
# No connection messaging: block — employee agents have no messaging channel.
# No MessagingSession linked variables — those are service-agent-only.
And line 181 (the "deliberately absent" list):
What's deliberately absent (vs. service agents):
- No
default_agent_user in config (agent runs as logged-in employee)
- No
connection messaging: block (no messaging channel)
- No
EndUserId/RoutableId/ContactId linked variables (no @MessagingSession)
- No
@utils.escalate action (requires connection messaging:)
The bolded line is contradicted by the UI output above — EndUserId, RoutableId, ContactId, and EndUserLanguage all appear on employee agents as visibility: "External" linked variables.
Error C2 — current* host-context variables are never mentioned anywhere in the skill
Grep across the entire skill (SKILL.md, all files under references/, all files under assets/):
currentRecordId — not mentioned
currentObjectApiName — not mentioned
currentPageType — not mentioned
currentAppName — not mentioned
- "host-context" / "host surface" — not mentioned (the two "visibility" hits in SKILL.md are coincidental)
These are the mutable string + visibility: "External" variables the Lightning Experience Agentforce panel populates at session start. Without them — or with them declared without visibility: "External" — an agent that wants to read "this account" / "the current record" context has no way to do so. It just sits there with a dead variable the host never writes.
This is the single most important piece of wiring for record-page-embedded employee agents, and the skill doesn't mention it once.
Error C3 — The visibility: attribute is undocumented
references/agent-script-core-language.md — no mention of visibility: as a variable declaration attribute, or External / Internal as values. (The two hits on "Internal" at lines 270 and 406 are for "Internal Error" in publish failures, and for subagent block ordering — neither describes the variable attribute.)
SKILL.md Syntax Quick Reference — no mention.
The attribute governs a contract with the host surface:
visibility: "External" — host surface populates this variable at session start
visibility: "Internal" — variable is hidden from the host
visibility: omitted — host never populates it, silently
A new author has no way to know this attribute exists from reading the skill.
Observed failure mode
An employee agent authored by following examples.md literally (e.g., declaring currentRecordId: mutable string = "" with no visibility: and no awareness of the reserved name contract):
| Check |
Result |
sf agent validate authoring-bundle |
✅ success: true |
sf agent preview start --use-live-actions |
✅ session starts, utterances return correct results for any path that doesn't depend on host context |
| Utterances referencing the currently-open record when the agent is embedded on a Lightning Record Page |
❌ host-context variable is empty at runtime; agent falls back to asking the user for the record's name |
The author cannot distinguish a correctly-wired agent from an incorrectly-wired one using any tool in the skill's workflow. Only interactive use in production surfaces the gap. There is no validator warning.
Suggested direction (not a prescribed fix)
Scope note: these suggestions don't change any existing correct content in the skill — they're additive (documenting what's missing) and corrective (fixing the one factually-incorrect exclusion list). Nothing here removes functionality or rewrites conceptual material.
A — Correct references/examples.md "Minimal Employee Agent":
- Remove the "service-agent-only" framing of
EndUserId / RoutableId / ContactId / EndUserLanguage on line 85 and in the deliberately-absent list at line 181.
- Rewrite the example's
variables: block using the UI-generated employee-agent baseline as the starting point (including current* with visibility: "External" and VerifiedCustomerId with visibility: "Internal" if it is part of the canonical baseline).
- Keep a separate custom-variables example to show author-defined state (like
search_query / article_id) alongside the platform variables, not replacing them.
B — Document visibility: in references/agent-script-core-language.md (and reference it from SKILL.md's Syntax Quick Reference):
- Syntax position on a variable declaration
"External" — host surface populates this variable at session start (and which hosts do so)
"Internal" — hidden from host
- Omitted — host never populates the variable (silent failure mode)
- Which variable names are recognized by the Lightning Record Page host:
currentAppName, currentObjectApiName, currentPageType, currentRecordId
C — Add a new reference file — something like references/employee-agent-host-context.md (or a section in examples.md):
- How employee agents receive context from Lightning Record Page, App Page, Home Page, Utility Bar
- The canonical list of reserved
current* variable names and what populates each
- The
@MessagingSession / @MessagingEndUser / @context.* availability matrix across Service / Employee / host-surface combinations
D — Add a silent-failure entry to references/production-gotchas.md (or known-issues.md):
If @variables.currentRecordId is always empty when the agent is embedded on a record page: check (1) visibility: "External" is present on the declaration, (2) the variable name exactly matches the host's recognized list (currentAppName, currentObjectApiName, currentPageType, currentRecordId). Validator + preview do not catch this; only interactive use on a real Lightning page surfaces it.
E — (Optional but high-value) note the scaffolder output. sf agent generate authoring-bundle currently emits a service-shaped template regardless of agent type. The skill should note that scaffolder output needs pruning/replacement for employee agents, pointing at the canonical baseline from A.
Open questions for the product team
These are the points where the skill maintainer would benefit from authoritative answers from the Agent Script / Agentforce product team before committing to exact wording. I'm listing them here because the issue otherwise invites "well, what exactly should the doc say about visibility?" — and a maintainer without platform-internal knowledge shouldn't have to guess.
On visibility:
- What is the default value when
visibility: is omitted on a variable? Does it differ between linked and mutable variables?
- Is
visibility: valid on linked variables at all, or does source: @... make it irrelevant? The service-agent UI emits linked variables without visibility:; the employee-agent UI emits the same names with visibility: "External". What does that difference do at runtime?
- Are there values beyond
External / Internal? Any ReadOnly, Hidden, channel-specific values?
- What does
External actually mean in terms of host-surface API — two-way contract, host-read-only, host-write-only?
On host-context variables
- Is
currentAppName / currentObjectApiName / currentPageType / currentRecordId the complete list, or are there more (e.g., currentUserId, currentLocale, currentOrgId, currentUrl)?
- Are the variable names themselves special (host looks for these exact strings) or is
visibility: "External" the actual contract, with any External variable settable by the host?
- Which host surfaces populate these variables — Lightning Copilot on Record Page, Experience Cloud, Service Cloud Voice, mobile, API sessions?
- On a non-record host (Home Page, App Page with no record), do
currentRecordId / currentObjectApiName resolve to empty string, null, or unset?
- Can employee agents declare additional External variables (beyond the four
current*) and have the host populate them, or is the population keyed to recognized names only?
On service-only variable groups
- Are
authenticationKey / customerId / customerType / isVerified platform-wired (the platform populates and reads them as part of a built-in verification protocol) or are they template defaults the author is expected to wire up manually?
- Same question for
emailCaseId / endUserEmail / endUserContactId in the email-to-case flow.
VerifiedCustomerId on both agent types — what populates it?
On MessagingSession variables on employee agents
- Why does the UI emit
@MessagingSession linked variables on employee agents? The skill's claim that employee agents "have no messaging channel" implies those sources can't resolve. Are they:
- Dead declarations that compile but never populate (UI-emission bug)?
- Populated in some employee contexts (e.g., an employee using a messaging tool)?
- Required metadata for some platform feature?
On documentation process
- Where is the official source of truth for host-context variable names and the
visibility: attribute today? Developer docs? Trailhead? Internal wiki? (The answer "the UI output, empirically" is what led to this report.)
- Does the Agent Script team have a process for keeping community-facing skills in sync with UI-emitted defaults as the platform evolves? If not, this class of drift will recur each release.
Evidence trail
- Skill version observed: current
main of SalesforceAIResearch/agentforce-adlc as of 2026-04-30.
- Variable blocks: copied directly from Agent Builder UI output for newly-created agents of each type (service and employee) on 2026-04-25. No manual edits.
- Validator confirmation:
sf agent validate authoring-bundle --json returned success: true on an AgentforceEmployeeAgent authored from the skill's "Minimal Employee Agent" example, despite the agent lacking the host-context wiring needed for the current* variables to be populated at runtime.
- Reproducer available on request: single-topic
AgentforceEmployeeAgent backed by invocable Apex, published and activated in target org, exhibiting the silent-failure mode described above.
Filed by Matt Wexler, Distinguished SE, Financial Services at Salesforce.
developing-agentforce: Employee Agent host-context variables produce silent runtime failure (examples.md wrong,visibility:undocumented,current*reserved names not mentioned)Target repo:
SalesforceAIResearch/agentforce-adlcSkill:
developing-agentforcePrimary files:
skills/developing-agentforce/references/examples.md— "Minimal Employee Agent" section (lines 63–182)skills/developing-agentforce/references/agent-script-core-language.md— Core Language reference (no coverage ofvisibility:or host-context vars)skills/developing-agentforce/SKILL.md— Syntax Quick Reference (no coverage of either)skills/developing-agentforce/references/production-gotchas.md— no entry for silent host-context failureSummary
The skill's "Minimal Employee Agent" example and surrounding references diverge from what the Salesforce Agent Builder UI actually emits when creating a new
AgentforceEmployeeAgent. The divergence isn't cosmetic — it causes a silent runtime failure that cannot be caught by any tool in the skill's workflow:sf agent validate authoring-bundlereturnssuccess: true)visibility:attribute, and theExternalcontract with the host surface.Concretely, three distinct errors in the skill's current content combine to produce the failure:
examples.md(line 181) assertsEndUserId/RoutableId/ContactId/EndUserLanguageare "service-agent-only." This is factually incorrect; the UI emits them on employee agents too.current*host-context variables (currentRecordId,currentObjectApiName,currentPageType,currentAppName) are the mechanism by which an embedded employee agent receives Lightning Record Page context. They are never mentioned anywhere in the skill — not inexamples.md, not inagent-script-core-language.md, not inSKILL.md, not inagent-design-and-spec-creation.md.visibility:attribute ("External"/"Internal"/ omitted) on variable declarations is undocumented. The Core Language reference and the Syntax Quick Reference never mention it. Butvisibility: "External"is what opts a variable in to being populated by the host surface. Without it, the host never writes — silently.Concrete failure case: an author building an employee agent that answers "what's the billing address for this account?" will, following the skill literally, declare
currentRecordId: mutable string = ""with novisibility:attribute. It compiles, validates, previews, publishes. Embedded on an Account record page,@variables.currentRecordIdis always empty. The instructionif @variables.currentRecordId is not emptybecomes dead code. The agent asks "which account?" even though the user is clearly on one. No validator warning fires.I hit this while building a single-topic employee agent for Account billing address lookups on 2026-04-25. All three errors below are documented against the current state of the skill files on
main, and all three show up in.agentoutput emitted by the Salesforce UI that contradicts the skill.Evidence
Evidence — UI-generated variable blocks (copied directly from Agent Builder output)
Service Agent (UI default, no manual edits):
Employee Agent (UI default, no manual edits):
Side-by-side (what the UI makes unambiguous):
authenticationKey/customerId/customerType/isVerifiedEndUserId/RoutableId/ContactId/EndUserLanguage(linked)visibility:attr)VerifiedCustomerIdemailCaseId/endUserEmail/endUserContactIdcurrentAppName/currentObjectApiName/currentPageType/currentRecordIdFour observations:
@MessagingSessionlinked variables appear on both agent types.visibility:attribute has three observable states:"External","Internal", and omitted. The service-agent UI output emits MessagingSession linked vars with novisibility:at all; the employee-agent UI output emits the same names withvisibility: "External". The semantic difference is undocumented.current*host-context variables only appear on employee agents. They are the mechanism for Lightning Record Page context.authenticationKey/customerId/customerType/isVerified) and an email-to-case trio (emailCaseId/endUserEmail/endUserContactId).Error C1 —
examples.mdwrongly excludes@MessagingSessionlinked variables from employee agentsskills/developing-agentforce/references/examples.md, line 85 (insideconfig:of Minimal Employee Agent):And line 181 (the "deliberately absent" list):
The bolded line is contradicted by the UI output above —
EndUserId,RoutableId,ContactId, andEndUserLanguageall appear on employee agents asvisibility: "External"linked variables.Error C2 —
current*host-context variables are never mentioned anywhere in the skillGrep across the entire skill (
SKILL.md, all files underreferences/, all files underassets/):currentRecordId— not mentionedcurrentObjectApiName— not mentionedcurrentPageType— not mentionedcurrentAppName— not mentionedThese are the
mutable string+visibility: "External"variables the Lightning Experience Agentforce panel populates at session start. Without them — or with them declared withoutvisibility: "External"— an agent that wants to read "this account" / "the current record" context has no way to do so. It just sits there with a dead variable the host never writes.This is the single most important piece of wiring for record-page-embedded employee agents, and the skill doesn't mention it once.
Error C3 — The
visibility:attribute is undocumentedreferences/agent-script-core-language.md— no mention ofvisibility:as a variable declaration attribute, orExternal/Internalas values. (The two hits on "Internal" at lines 270 and 406 are for "Internal Error" in publish failures, and for subagent block ordering — neither describes the variable attribute.)SKILL.mdSyntax Quick Reference — no mention.The attribute governs a contract with the host surface:
visibility: "External"— host surface populates this variable at session startvisibility: "Internal"— variable is hidden from the hostvisibility:omitted — host never populates it, silentlyA new author has no way to know this attribute exists from reading the skill.
Observed failure mode
An employee agent authored by following
examples.mdliterally (e.g., declaringcurrentRecordId: mutable string = ""with novisibility:and no awareness of the reserved name contract):sf agent validate authoring-bundlesuccess: truesf agent preview start --use-live-actionsThe author cannot distinguish a correctly-wired agent from an incorrectly-wired one using any tool in the skill's workflow. Only interactive use in production surfaces the gap. There is no validator warning.
Suggested direction (not a prescribed fix)
A — Correct
references/examples.md"Minimal Employee Agent":EndUserId/RoutableId/ContactId/EndUserLanguageon line 85 and in the deliberately-absent list at line 181.variables:block using the UI-generated employee-agent baseline as the starting point (includingcurrent*withvisibility: "External"andVerifiedCustomerIdwithvisibility: "Internal"if it is part of the canonical baseline).search_query/article_id) alongside the platform variables, not replacing them.B — Document
visibility:inreferences/agent-script-core-language.md(and reference it fromSKILL.md's Syntax Quick Reference):"External"— host surface populates this variable at session start (and which hosts do so)"Internal"— hidden from hostcurrentAppName,currentObjectApiName,currentPageType,currentRecordIdC — Add a new reference file — something like
references/employee-agent-host-context.md(or a section inexamples.md):current*variable names and what populates each@MessagingSession/@MessagingEndUser/@context.*availability matrix across Service / Employee / host-surface combinationsD — Add a silent-failure entry to
references/production-gotchas.md(orknown-issues.md):E — (Optional but high-value) note the scaffolder output.
sf agent generate authoring-bundlecurrently emits a service-shaped template regardless of agent type. The skill should note that scaffolder output needs pruning/replacement for employee agents, pointing at the canonical baseline from A.Open questions for the product team
These are the points where the skill maintainer would benefit from authoritative answers from the Agent Script / Agentforce product team before committing to exact wording. I'm listing them here because the issue otherwise invites "well, what exactly should the doc say about visibility?" — and a maintainer without platform-internal knowledge shouldn't have to guess.
On
visibility:visibility:is omitted on a variable? Does it differ betweenlinkedandmutablevariables?visibility:valid onlinkedvariables at all, or doessource: @...make it irrelevant? The service-agent UI emitslinkedvariables withoutvisibility:; the employee-agent UI emits the same names withvisibility: "External". What does that difference do at runtime?External/Internal? AnyReadOnly,Hidden, channel-specific values?Externalactually mean in terms of host-surface API — two-way contract, host-read-only, host-write-only?On host-context variables
currentAppName/currentObjectApiName/currentPageType/currentRecordIdthe complete list, or are there more (e.g.,currentUserId,currentLocale,currentOrgId,currentUrl)?visibility: "External"the actual contract, with anyExternalvariable settable by the host?currentRecordId/currentObjectApiNameresolve to empty string, null, or unset?current*) and have the host populate them, or is the population keyed to recognized names only?On service-only variable groups
authenticationKey/customerId/customerType/isVerifiedplatform-wired (the platform populates and reads them as part of a built-in verification protocol) or are they template defaults the author is expected to wire up manually?emailCaseId/endUserEmail/endUserContactIdin the email-to-case flow.VerifiedCustomerIdon both agent types — what populates it?On MessagingSession variables on employee agents
@MessagingSessionlinked variables on employee agents? The skill's claim that employee agents "have no messaging channel" implies those sources can't resolve. Are they:On documentation process
visibility:attribute today? Developer docs? Trailhead? Internal wiki? (The answer "the UI output, empirically" is what led to this report.)Evidence trail
mainofSalesforceAIResearch/agentforce-adlcas of 2026-04-30.sf agent validate authoring-bundle --jsonreturnedsuccess: trueon anAgentforceEmployeeAgentauthored from the skill's "Minimal Employee Agent" example, despite the agent lacking the host-context wiring needed for thecurrent*variables to be populated at runtime.AgentforceEmployeeAgentbacked by invocable Apex, published and activated in target org, exhibiting the silent-failure mode described above.Filed by Matt Wexler, Distinguished SE, Financial Services at Salesforce.