microsoft / microsoft/AdaptiveCards
[Rendering] Adaptive Card from a custom engine agent fails to render in Microsoft 365 Copilot mobile (no card) and renders text-only (elements dropped) in Copilot chat
Nobody has claimed this yet.
- Dominant language
- C#
- Stars
- 2k
- Forks
- 595
- Avg merge
- 1d 19h
- Merged PRs (30d)
- 1
Description
Target Platforms
Android, iOS
SDK Version
Agent framework: Microsoft 365 Agents SDK — @microsoft/agents-hosting `1.3.1
Application Name
Microsoft Teams Copilot Chat & M365 Copilot Chat
Problem Description
Bug Report — Adaptive Card rendering on Microsoft 365 Copilot (mobile / Copilot chat)
Draft for filing against https://github.com/microsoft/AdaptiveCards (structure based on issue #9315).
All details are sourced only from theloopio_ms_teamsrepository.
Title
[Rendering] Adaptive Card from a custom engine agent fails to render in Microsoft 365 Copilot mobile (no card) and renders text-only (elements dropped) in Copilot chat
Target platforms
- iOS
- Android
SDK / Application versions
- Agent framework: Microsoft 365 Agents SDK —
@microsoft/agents-hosting1.3.1,@microsoft/agents-activity1.3.1 - Agent type: Custom engine agent (bot); failing surface reports
channelId = "msteams:COPILOT"(sub-channelCOPILOT) - Adaptive Card schema versions tried:
1.6,1.5,1.4— same result - Delivery method: Bot Framework activity attachment —
contentType: application/vnd.microsoft.card.adaptiveviacontext.sendActivity(MessageFactory.attachment(card))
Description / Problem
A custom engine agent (Microsoft 365 Agents SDK) returns an Adaptive Card as a bot activity attachment. The card renders correctly on Microsoft Teams (desktop and mobile app) and on Microsoft 365 Copilot desktop/web, but fails on Copilot surfaces as follows:
- Microsoft 365 Copilot — mobile app (iOS & Android): no response renders at all. The agent's reply (the Adaptive Card message) does not appear in the conversation.
- Teams Copilot chat: the card renders only its top-level
TextBlock; all other elements are dropped — the per-itemContainerand its nestedActionSet(withAction.OpenUrlandAction.Submitbuttons) do not render. Notably, when anActionSetis nested inside aContainer, the entire parentContainerdisappears (so its childTextBlocks vanish too), leaving only the root-level title. (Other Adaptive Cards produced by this same agent are affected the same way:FactSet— used by the help/commands card — andBadge/ColumnSet— used to display entry tags — also fail to render on these surfaces.)
Additionally, the SDK-generated OAuth sign-in card (application/vnd.microsoft.card.oauth) does not render its sign-in button on these surfaces — only the card's fallback text shows — so users cannot authenticate.
Steps to reproduce
- Build a custom engine agent with the Microsoft 365 Agents SDK (
@microsoft/agents-hosting1.3.1) and publish it to Microsoft 365 Copilot. - From the bot, send the Adaptive Card below using
context.sendActivity(MessageFactory.attachment(card)). - Trigger the response in Microsoft 365 Copilot on iOS/Android → observe no card appears.
- Trigger the same response in Copilot chat → observe only the top-level title renders; the entry
Containerand its buttons are dropped. - For comparison, trigger the same agent/card in the Microsoft Teams client (desktop and mobile app) and Copilot desktop/web → renders fully.
Expected behavior
The full card — title, the per-entry Container with its TextBlocks, and the ActionSet with Action.OpenUrl / Action.Submit buttons — renders on Microsoft 365 Copilot mobile and Copilot chat, as it does on Teams and Copilot desktop/web.
Actual behavior
- M365 Copilot mobile (iOS/Android): nothing renders — no card/message at all.
- Copilot chat: only the top-level
TextBlock("Library Entries") renders; each per-entryContainer(text +ActionSet) is entirely dropped.
Observed: mobile Copilot shows nothing; Copilot chat shows only "Library Entries".
Sample code language
TypeScript (Node.js)
Sample code (how the card is delivered)
import { MessageFactory } from '@microsoft/agents-hosting';
const response = MessageFactory.attachment({
contentType: 'application/vnd.microsoft.card.adaptive',
content: card, // the JSON above
});
await context.sendActivity(response);
The OAuth sign-in card is delivered by the Agents SDK's built-in AgentApplication authorization handler (application/vnd.microsoft.card.oauth); its sign-in button does not render on these Copilot surfaces either.
Works correctly on (not affected)
- Microsoft Teams mobile app (iOS & Android): the same card renders fully, including all buttons — this is the expected behavior.
- Microsoft Teams desktop: renders fully.
- Microsoft 365 Copilot — desktop/web: renders fully.
Key point: on the same iOS/Android device, the Microsoft Teams app renders the card correctly, while the Microsoft 365 Copilot mobile app / Copilot chat does not. The only failing surfaces are M365 Copilot mobile (no card at all) and Copilot chat (text-only). Since the identical agent and identical card work on Teams (desktop and mobile) and on Copilot desktop/web, this isolates the problem to the Microsoft 365 Copilot client renderer — not the mobile OS, not the card content, and not the schema version (reproduced on both 1.5 and 1.6, 1.4).
Additional environment notes
- The failing surface reports
channelId = "msteams:COPILOT"(sub-channelCOPILOT). The incoming activity'sclientInfoentity contains noplatformfield, so device type (mobile vs desktop) is not distinguishable from the activity payload.
Not Working
https://github.com/user-attachments/assets/239c3b24-6bbd-4f99-870d-16ffa7e44963
https://github.com/user-attachments/assets/9b6d47ed-5877-4906-bb17-690a1bc8b6b7
Working on Web
Screenshots
No response
Card JSON
{"type":"AdaptiveCard","version":"1.6","body":[{"type":"TextBlock","text":"Library Entries","weight":"Bolder","size":"Large"},{"type":"Container","separator":true,"spacing":"Medium","items":[{"type":"TextBlock","text":"test question","wrap":true,"weight":"Bolder","size":"Medium"},{"type":"TextBlock","text":"COMPANY","wrap":true,"isSubtle":true,"size":"Small"},{"type":"TextBlock","text":"test answer","wrap":true,"spacing":"Small"},{"type":"TextBlock","text":"Created by Jane Doe on 2026-06-10","wrap":true,"isSubtle":true,"size":"Small","spacing":"Small"},{"type":"ActionSet","actions":[{"type":"Action.OpenUrl","title":"View in Loopio","iconUrl":"icon:Open","url":"https://app.example.com/library/view/12345"},{"type":"Action.Submit","title":"See Full Entry","style":"positive","data":{"msteams":{"type":"messageBack","displayText":"","text":"Post - 12345, https://app.example.com/library/view/12345","value":"Post - 12345, https://app.example.com/library/view/12345"}}},{"type":"Action.Submit","title":"Summarize","style":"positive","data":{"msteams":{"type":"messageBack","displayText":"","text":"Summarize - 12345, https://app.example.com/library/view/12345","value":"Summarize - 12345, https://app.example.com/library/view/12345"}}}]}]},{"type":"Container","separator":true,"spacing":"Medium","items":[{"type":"TextBlock","text":"qa test","wrap":true,"weight":"Bolder","size":"Medium"},{"type":"TextBlock","text":"COMPANY","wrap":true,"isSubtle":true,"size":"Small"},{"type":"TextBlock","text":"QA ans","wrap":true,"spacing":"Small"},{"type":"TextBlock","text":"Created by Jane Doe on 2026-06-09","wrap":true,"isSubtle":true,"size":"Small","spacing":"Small"},{"type":"ActionSet","actions":[{"type":"Action.OpenUrl","title":"View in Loopio","iconUrl":"icon:Open","url":"https://app.example.com/library/view/12346"},{"type":"Action.Submit","title":"See Full Entry","style":"positive","data":{"msteams":{"type":"messageBack","displayText":"","text":"Post - 12346, https://app.example.com/library/view/12346","value":"Post - 12346, https://app.example.com/library/view/12346"}}},{"type":"Action.Submit","title":"Summarize","style":"positive","data":{"msteams":{"type":"messageBack","displayText":"","text":"Summarize - 12346, https://app.example.com/library/view/12346","value":"Summarize - 12346, https://app.example.com/library/view/12346"}}}]}]},{"type":"Container","separator":true,"spacing":"Medium","items":[{"type":"TextBlock","text":"Question 1","wrap":true,"weight":"Bolder","size":"Medium"},{"type":"TextBlock","text":"PRODUCT","wrap":true,"isSubtle":true,"size":"Small"},{"type":"TextBlock","text":"answer 1","wrap":true,"spacing":"Small"},{"type":"TextBlock","text":"Created by Jane Doe on 2026-06-09","wrap":true,"isSubtle":true,"size":"Small","spacing":"Small"},{"type":"ActionSet","actions":[{"type":"Action.OpenUrl","title":"View in Loopio","iconUrl":"icon:Open","url":"https://app.example.com/library/view/12347"},{"type":"Action.Submit","title":"See Full Entry","style":"positive","data":{"msteams":{"type":"messageBack","displayText":"","text":"Post - 12347, https://app.example.com/library/view/12347","value":"Post - 12347, https://app.example.com/library/view/12347"}}},{"type":"Action.Submit","title":"Summarize","style":"positive","data":{"msteams":{"type":"messageBack","displayText":"","text":"Summarize - 12347, https://app.example.com/library/view/12347","value":"Summarize - 12347, https://app.example.com/library/view/12347"}}}]}]}],"$schema":"https://adaptivecards.io/schemas/adaptive-card.json"}
Sample Code Language
No response
Sample Code
No response
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start by reproducing the sample card through context.sendActivity(MessageFactory.attachment(card)) on Microsoft 365 Copilot mobile and Copilot chat, then compare it with Teams and Copilot desktop/web. Also inspect the AgentApplication authorization handler for the OAuth card behavior. Done means the full card elements, actions, and OAuth sign-in button render on the failing Copilot surfaces.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- node.js, typescript
- Domain
- frontend, mobile-dev
- Issue type
- Bug
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Quiet
- Clarity
- Needs clarification
- Newbie friendliness
- 25/100