Skip to content

External Skill Actions fail silently on SharePoint and M365 Copilot channels (responses not relayed to user) #576

Description

@ejazhussain

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.

Image

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.

Image

4. SharePoint shows nothing

Despite the skill completing successfully, the user sees no response in SharePoint

Image

5. M365 Copilot shows fallback message

Same behavior in the M365 Copilot sidebar.

Image

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:

  1. The channels themselves work fine for native Copilot Studio message delivery
  2. The external skill Action invocation is the specific failure point on these channels
  3. 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

Metadata

Metadata

Assignees

Labels

Copilot StudioThis issue is related to Microsoft Copilot Studio

Type

No type
No fields configured for issues without a type.

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions