Bug type
Behavior bug (incorrect output/state without crash)
Summary
When users attach files (PDFs, images, etc.) to Teams channel messages, the bot cannot see or access the file content. The LLM only receives the text portion of the message.
Additionally, the Graph API media fallback path fires excessively for non-file messages (any message with @mentions), generating misleading [DEBUG-MEDIA] graph media fetch empty error logs.
Version
- OpenClaw: 2026.3.24 (also checked 2026.3.31 — same behavior)
- Channel: msteams (bundled plugin)
Analysis
Two related problems:
1. Graph fallback triggers on @mention HTML cards (false positive)
The fallback condition in resolveMSTeamsInboundMedia() is:
if (attachments.length > 0 && attachments.every(att =>
String(att.contentType ?? "").startsWith("text/html")))
Teams delivers @mention formatting as text/html Bot Framework attachments. So every @BotName message triggers the Graph API media fallback, even when there's no file. This produces noisy [DEBUG-MEDIA] graph media fetch empty error-level logs with attachmentStatus: 404 (the /attachments sub-resource doesn't exist in Graph API v1.0 for channel messages).
2. Actual file uploads may not be processed correctly
For channel file uploads, Teams stores the file in SharePoint and the Graph API message includes a contentType: "reference" attachment with a SharePoint contentUrl. The plugin code handles this path:
- Fetches message body via Graph → finds
reference attachments → downloads via /shares/u!{base64url}/driveItem/content
However, in practice:
- The Bot Framework activity for channel file uploads delivers the file info as
text/html cards, not as application/vnd.microsoft.teams.file.download.info attachments (which is the DM format)
- The Graph fallback should find the
reference attachment in the message body, but it's unclear if the activity.id used to construct the Graph URL always matches the Graph message ID
- Some Graph fetches return
hostedStatus: 404 for the first candidate URL, suggesting activity ID → Graph message ID mismatch
Expected Behavior
- File attachments uploaded in Teams channels should be downloaded and included in the LLM context
- The Graph fallback should NOT trigger for messages that only have @mention HTML cards (no actual file content)
- The
${messageUrl}/attachments endpoint (which returns 404 since it doesn't exist in Graph v1.0) should not be called — file attachments are in the message body's attachments array, not a sub-resource
Steps to Reproduce
- Configure the msteams channel plugin with appropriate Graph API permissions (
ChannelMessage.Read.All, Files.Read.All)
- In a Teams channel, upload a PDF and @mention the bot asking about the file
- The bot responds that it cannot see the file
- Logs show
[DEBUG-MEDIA] graph media fetch empty with attachmentStatus: 404
Suggested Improvements
- Skip Graph fallback for mention-only HTML attachments — Check if the HTML contains
<attachment> tags before triggering the fallback. Pure <at> mention cards should not trigger media download.
- Remove the
/attachments sub-resource fetch — This endpoint doesn't exist in Graph v1.0 for channel/chat messages. The attachment data is already in the message body response.
- Verify activity ID → Graph message ID mapping — The Bot Framework
activity.id may not always correspond to the Graph API message ID for channel messages.
Bug type
Behavior bug (incorrect output/state without crash)
Summary
When users attach files (PDFs, images, etc.) to Teams channel messages, the bot cannot see or access the file content. The LLM only receives the text portion of the message.
Additionally, the Graph API media fallback path fires excessively for non-file messages (any message with @mentions), generating misleading
[DEBUG-MEDIA] graph media fetch emptyerror logs.Version
Analysis
Two related problems:
1. Graph fallback triggers on @mention HTML cards (false positive)
The fallback condition in
resolveMSTeamsInboundMedia()is:Teams delivers @mention formatting as
text/htmlBot Framework attachments. So every@BotNamemessage triggers the Graph API media fallback, even when there's no file. This produces noisy[DEBUG-MEDIA] graph media fetch emptyerror-level logs withattachmentStatus: 404(the/attachmentssub-resource doesn't exist in Graph API v1.0 for channel messages).2. Actual file uploads may not be processed correctly
For channel file uploads, Teams stores the file in SharePoint and the Graph API message includes a
contentType: "reference"attachment with a SharePointcontentUrl. The plugin code handles this path:referenceattachments → downloads via/shares/u!{base64url}/driveItem/contentHowever, in practice:
text/htmlcards, not asapplication/vnd.microsoft.teams.file.download.infoattachments (which is the DM format)referenceattachment in the message body, but it's unclear if theactivity.idused to construct the Graph URL always matches the Graph message IDhostedStatus: 404for the first candidate URL, suggesting activity ID → Graph message ID mismatchExpected Behavior
${messageUrl}/attachmentsendpoint (which returns 404 since it doesn't exist in Graph v1.0) should not be called — file attachments are in the message body'sattachmentsarray, not a sub-resourceSteps to Reproduce
ChannelMessage.Read.All,Files.Read.All)[DEBUG-MEDIA] graph media fetch emptywithattachmentStatus: 404Suggested Improvements
<attachment>tags before triggering the fallback. Pure<at>mention cards should not trigger media download./attachmentssub-resource fetch — This endpoint doesn't exist in Graph v1.0 for channel/chat messages. The attachment data is already in the message body response.activity.idmay not always correspond to the Graph API message ID for channel messages.