Mastering Table Variables in Copilot Studio: Add, Remove, and Clear via YAML
Discover how the hidden EditTable YAML node lets you dynamically add, remove, or clear table variables directly inside your copilot conversations.
When building sophisticated assistants in Copilot Studio, you often need to store lists of items — such as team members, tasks, or event attendees — and dynamically update them during a conversation. While the standard node palette doesn't include a dedicated "Edit Table" action, the underlying YAML engine exposes a hidden EditTable node that lets you add, remove, or clear records from any table variable. In this article, we'll walk through a realistic scenario: a Conference Speaker Manager that tracks confirmed speakers and their session details.
Scenario Overview
Imagine a conference organizer uses a Copilot Studio agent to manage the speaker roster. The agent maintains a table variable Global.SpeakerList that holds records with two columns: FullName and Topic. The organizer can ask the agent to add a new speaker, remove an existing speaker, or clear the entire list. All these operations are performed using the hidden EditTable node, which we'll configure through the code editor.
Let's set up this agent step by step.
1. Create and Initialize the Table Variable
Start by creating a new Copilot Studio agent called Conference Speaker Manager. Give it the following description and general instructions:
- Description: Assists organizers by managing the speaker list for conference sessions.
- General Instructions:
- Determine the user's intent: add a speaker, remove a speaker, or clear the speaker list.
- Run the appropriate topic: "Add Speaker", "Remove Speaker", or "Clear Speakers".
Open the Conversation Start topic. Here we'll create the Global.SpeakerList variable and seed it with three initial speakers. Use the following Power Fx formula inside an Assign node (set the variable to Table):
Table(
{FullName: "Alice Johnson", Topic: "AI Ethics"},
{FullName: "Bob Smith", Topic: "Cloud Architecture"},
{FullName: "Carol Lee", Topic: "UX Design"}
)Then edit the first Message node to display the current speaker list as a bulleted list. Use the Concat function to generate the HTML:
Hello, I'm the **{Bot.Name}**.
The confirmed speakers so far are:
<ul>
{Concat(Global.SpeakerList, "<li>" & FullName & " – " & Topic & "</li>")}
</ul>
What would you like to do? Add a speaker, remove a speaker, or clear the entire list?2. Adding a Record to the Table Variable
Now let's create the Add Speaker topic. This topic will ask for the new speaker's name and session topic, then use an EditTable node to append a record.
Design the topic like this:
- Trigger: "Add a speaker"
- Question: "What is the speaker's full name?" → store in
Topic.SpeakerName - Question: "What is their session topic?" → store in
Topic.SessionTopic - Then call the hidden EditTable action.
The EditTable node cannot be added from the nodes menu — you must insert it through the YAML code editor. After the last question, open the code editor (toggle the </> icon) and paste the following YAML snippet:
- kind: EditTable
id: editTable_Add01
displayName: Add New Speaker
changeType: Add
itemsVariable: Global.SpeakerList
resultVariable: Global.SpeakerList
value: "={FullName: Topic.SpeakerName, Topic: Topic.SessionTopic}"Close the code editor and you'll see the Add New Speaker node appear in your topic. Its action property is automatically set to "Add a new record".
After the EditTable node, add a Message node to confirm the addition, e.g.:
Speaker **{Topic.SpeakerName}** has been added to the list.3. Removing a Record from the Table Variable
To remove a speaker, create a Remove Speaker topic.
- Trigger: "Remove a speaker"
- Question: "What is the full name of the speaker you want to remove?" → store in
Topic.SpeakerName - Insert an EditTable node via code editor with the following YAML:
- kind: EditTable
id: editTable_Remove01
displayName: Remove Speaker
changeType: Remove
itemsVariable: Global.SpeakerList
resultVariable: Global.SpeakerList
value: "={FullName: Topic.SpeakerName, Topic: Topic.SessionTopic}"You can also remove based only on a partial match of columns. In this example, the node will remove the first record where FullName matches the provided name. Note that the value property must contain an expression that resolves to a record matching the table's schema — even if you only want to match a subset of columns.
Add a confirmation message after the node.
4. Clearing the Table Variable
When an organizer wants to start fresh, they can clear the entire Global.SpeakerList. Create a Clear Speakers topic.
- Trigger: "Clear the speaker list"
- Insert an EditTable node with this YAML:
- kind: EditTable id: editTable_Clear01 displayName: Clear Speaker List changeType: Clear itemsVariable: Global.SpeakerList resultVariable: Global.SpeakerList
You don't need a value property for the clear action. After the node, add a message like "All speakers have been removed."
As an alternative, you can set Global.SpeakerList to Blank() — but using EditTable is more explicit and keeps the node's purpose visible in the topic flow.
Security & Performance Considerations
- Table variables are in‑memory and scoped to the conversation. They are ideal for small to medium datasets (up to a few hundred records). They are not suitable for large-scale data manipulation due to memory constraints.
- No delegation concerns arise because all operations occur in the copilot engine — there's no external data source involved.
- The values in the
valueproperty of EditTable are Power Fx expressions. Use proper quoting and escaping to avoid YAML parsing errors. For instance, the expression must start with=and use double quotes inside the YAML string. - Only one EditTable node per topic can use the same
changeTypeon the same table variable without unexpected results.
Common Mistakes & Troubleshooting
- Node does not appear after pasting YAML: Check the YAML indentation (must be 2 spaces per level). Also ensure the
kindfield is exactlyEditTable. - "value" is not recognized: If you omit the
valueproperty for Add or Remove actions, the node will fail. For add, you must provide a record. For remove, provide at least the column that identifies the record. - Variable casing: Variable names in Copilot Studio are case‑sensitive. Confirm that
itemsVariableandresultVariableexactly match the variable name (including theGlobal.prefix if applicable). - Concat in message returns nothing: Ensure your table variable is not empty. If it is, the
<ul>will still appear but without list items. You can handle this with anIfcheck.
Final Recommendation
The hidden EditTable node is a powerful yet underexposed feature in Copilot Studio. By using YAML directly, you can perform table operations that would otherwise require complex workarounds with Power Automate flows or custom actions. Use it to build more dynamic assistants — from staffing agents to event planners — without leaving the copilot environment.
References
- Original source that inspired this article: Matthew Devaney – Add A Record To A Table Variable In Copilot Studio
- Microsoft Learn: Copilot Studio table variables (placeholder – see official docs for latest syntax)
- Microsoft Learn: Power Fx Table function (placeholder – note that table variable usage may vary)