Description
External skills built with the Microsoft 365 Agents SDK (v1.5, .NET 10) execute successfully when invoked from Copilot Studio topics on SharePoint and M365 Copilot channels, but the skill's response activities are never delivered to the end user. The user sees the generic fallback message: "Sorry, I wasn't able to respond to that. Is there something else I can help with?"
The same skill works correctly on:
- ✅ Teams Bot chat (full multi-turn, authenticated)
- ✅ Demo website / Direct Line (full multi-turn, no auth)
- ✅ Copilot Studio test panel (single-turn only — multi-turn fails due to
expectReplies, which is a separate known limitation)
The skill fails on:
- ❌ SharePoint channel
- ❌ M365 Copilot sidebar
This limitation is not documented anywhere — not in the skill implementation docs, the quotas and limits page, the known issues page, or the SDK sample README.
Environment
| Component |
Value |
| Agents SDK version |
1.5 (.NET 10) |
| Copilot Studio region |
UK (uk-il101) |
| Tenant type |
Single-tenant |
| Auth setting |
Authenticate with Microsoft (Entra ID SSO) |
| Hosting |
Local with ngrok tunnel |
| Copilot Studio publish date |
17/05/2026 |
Steps to Reproduce
1. Create and deploy an external skill
Build a simple single-turn skill using the Agents SDK that:
- Receives a message
- Creates a ticket (or any operation)
- Sends an
EndOfConversation activity
- Returns 200 OK
private async Task OnMessageAsync(ITurnContext ctx, ITurnState state, CancellationToken ct)
{
var input = ctx.Activity.Text?.Trim() ?? string.Empty;
var ticket = await _tickets.CreateTicketAsync(new CreateTicketRequest
{
Title = input,
Priority = "Medium",
AffectedSystem = "Unknown",
ReportedBy = ctx.Activity.From?.Name ?? "Unknown"
}, ct);
var eoc = Activity.CreateEndOfConversationActivity();
eoc.Value = System.Text.Json.JsonSerializer.Serialize(new
{
ticketId = ticket.Id,
title = ticket.Title,
priority = ticket.Priority.ToString(),
affectedSystem = ticket.AffectedSystem,
status = ticket.Status.ToString()
});
await ctx.SendActivityAsync(eoc, cancellationToken: ct);
}
2. Register the skill in Copilot Studio
- Import the skill manifest into a Copilot Studio agent
- Create a topic with a trigger and an Action node that invokes the skill
- Publish the agent to SharePoint and M365 Copilot channels
3. Test on SharePoint channel
- Open the SharePoint site where the agent is deployed
- Type a trigger phrase (e.g. "I have an IT Issue")
- Expected: Skill response displayed to user
- Actual: "Sorry, I wasn't able to respond to that."
4. Test on M365 Copilot sidebar
- Open the agent in the M365 Copilot sidebar
- Type a trigger phrase
- Expected: Skill response displayed to user
- Actual: "Sorry, I wasn't able to respond to that."
Evidence
1. Skill executes successfully — confirmed via ngrok inspection
The inbound request from Copilot Studio reaches the skill correctly:
{
"type": "message",
"channelId": "m365copilot",
"text": "I have a IT Issue",
"serviceUrl": "https://pvaruntime.uk-il101.gateway.prod.island.powerapps.com/api/runtime/bots/.../skillsV2",
"from": {
"id": "2a5de346-...",
"role": "user"
},
"recipient": {
"id": "Default-.../...",
"name": "cr20c_itHelpdeskTicketLogger",
"role": "skill"
}
}
The skill processes the request, returns 200 OK, and POSTs response activities back to the serviceUrl. The pvaruntime endpoint also returns 200 OK.
1. Copilot Studio Activity log shows completed execution
The Activity log in Copilot Studio shows the topic matched, the skill executed in 0.76–1.00s, and the status is Completed. The skill's response content is visible in the activity trace.
3. Session transcript captures the skill response
The Session Transcript in Copilot Studio shows the full conversation including the skill's response message — proving the runtime received it. However, the SharePoint channel never relayed it to the user. Session status: Abandoned · User exit.
4. SharePoint shows nothing
Despite the skill completing successfully, the user sees no response in SharePoint
5. M365 Copilot shows fallback message
Same behavior in the M365 Copilot sidebar.
Isolation Tests Performed
To isolate the root cause, the following tests were conducted:
| Test |
Result |
Conclusion |
| Multi-turn skill → Teams Bot chat |
✅ Works |
Skill code is correct |
| Multi-turn skill → Demo website |
✅ Works |
Skill code is correct |
| Multi-turn skill → SharePoint |
❌ Fails |
Channel-specific issue |
| Multi-turn skill → M365 Copilot |
❌ Fails |
Channel-specific issue |
| Single-turn skill (EndOfConversation only) → SharePoint |
❌ Fails |
Not a multi-turn issue |
| Single-turn skill → M365 Copilot |
❌ Fails |
Not a multi-turn issue |
| Topic with NO skill Action (static message only) → SharePoint |
✅ Works |
Confirms skill Action is the failure point |
| Topic with NO skill Action (static message only) → M365 Copilot |
✅ Works |
Confirms skill Action is the failure point |
Key finding
When the skill Action node is removed from the topic and replaced with a static Message node, both SharePoint and M365 Copilot display the message correctly. This proves:
- The channels themselves work fine for native Copilot Studio message delivery
- The external skill Action invocation is the specific failure point on these channels
- The pvaruntime gateway accepts skill responses but does not relay them to these channel surfaces
Expected Behavior
External skill Actions should work consistently across all published channels — or at minimum, the channel-specific limitations should be clearly documented in:
Labels
bug, documentation, copilot-studio, skills, channels
Description
External skills built with the Microsoft 365 Agents SDK (v1.5, .NET 10) execute successfully when invoked from Copilot Studio topics on SharePoint and M365 Copilot channels, but the skill's response activities are never delivered to the end user. The user sees the generic fallback message: "Sorry, I wasn't able to respond to that. Is there something else I can help with?"
The same skill works correctly on:
expectReplies, which is a separate known limitation)The skill fails on:
This limitation is not documented anywhere — not in the skill implementation docs, the quotas and limits page, the known issues page, or the SDK sample README.
Environment
Steps to Reproduce
1. Create and deploy an external skill
Build a simple single-turn skill using the Agents SDK that:
EndOfConversationactivity2. Register the skill in Copilot Studio
3. Test on SharePoint channel
4. Test on M365 Copilot sidebar
Evidence
1. Skill executes successfully — confirmed via ngrok inspection
The inbound request from Copilot Studio reaches the skill correctly:
{ "type": "message", "channelId": "m365copilot", "text": "I have a IT Issue", "serviceUrl": "https://pvaruntime.uk-il101.gateway.prod.island.powerapps.com/api/runtime/bots/.../skillsV2", "from": { "id": "2a5de346-...", "role": "user" }, "recipient": { "id": "Default-.../...", "name": "cr20c_itHelpdeskTicketLogger", "role": "skill" } }The skill processes the request, returns 200 OK, and POSTs response activities back to the
serviceUrl. The pvaruntime endpoint also returns 200 OK.1. Copilot Studio Activity log shows completed execution
The Activity log in Copilot Studio shows the topic matched, the skill executed in 0.76–1.00s, and the status is Completed. The skill's response content is visible in the activity trace.
3. Session transcript captures the skill response
The Session Transcript in Copilot Studio shows the full conversation including the skill's response message — proving the runtime received it. However, the SharePoint channel never relayed it to the user. Session status: Abandoned · User exit.
4. SharePoint shows nothing
Despite the skill completing successfully, the user sees no response in SharePoint
5. M365 Copilot shows fallback message
Same behavior in the M365 Copilot sidebar.
Isolation Tests Performed
To isolate the root cause, the following tests were conducted:
Key finding
When the skill Action node is removed from the topic and replaced with a static Message node, both SharePoint and M365 Copilot display the message correctly. This proves:
Expected Behavior
External skill Actions should work consistently across all published channels — or at minimum, the channel-specific limitations should be clearly documented in:
Labels
bug,documentation,copilot-studio,skills,channels