-
-
Notifications
You must be signed in to change notification settings - Fork 69.5k
MS Teams: graph media fetch empty for channel file attachments despite valid permissions and token #51749
Description
Summary
MS Teams channel file attachments (PDFs, documents) are never delivered to the agent. The plugin logs graph media fetch empty on every inbound file, despite all Graph API permissions being correctly configured and working when tested manually.
Environment
- OpenClaw: 2026.3.13 (Docker)
- Node: 24.14.0
- Bot Framework SDK: @microsoft/agents-hosting 1.4.1
- Conversation type: channel (Teams team)
Symptoms
- User uploads a file in a Teams channel
- Bot Framework delivers the activity with
contentType: "text/html"attachment (HTML card) downloadMSTeamsAttachmentsreturns empty (expected — HTML cards are not directly downloadable)- Plugin enters Graph API fallback path (
onlyHtmlAttachments = true) buildMSTeamsGraphMessageUrlsbuilds correct URL (verified)downloadMSTeamsGraphMediareturns{ media: [] }— this is the bug- Agent receives message text but no file content
What works (tested manually from inside the container)
All of these succeed when called directly with the same credentials:
- MSAL token acquisition —
MsalTokenProvider.getAccessToken("https://graph.microsoft.com")returns valid token ( chars) - Graph message fetch —
GET /teams/{teamId}/channels/{channelId}/messages/{messageId}returns 200 withattachments[0].contentType: "reference"and valid SharePointcontentUrl - SharePoint download via shares API —
GET /shares/u!{base64url}/driveItem/contentreturns 200, downloads full PDF ( bytes) - SSRF guard —
fetchWithSsrFGuardwith the same policy passes forgraph.microsoft.com(returns 401 with fake token, not blocked) - isUrlAllowed — SharePoint URL passes allowlist check
Graph API Permissions (all granted with admin consent)
Application:
ChannelMessage.Read.AllChatMessage.Read.AllChat.Read.AllFiles.Read.AllGroup.Read.AllSites.ReadWrite.All
Delegated:
Chat.ReadWriteChannelMessage.ReadWrite.AllFiles.ReadWrite.AllUser.Read
Configuration
{
"mediaAllowHosts": ["*.sharepoint.com", "*.microsoft.com", "*.teams.microsoft.com", "*.graph.microsoft.com", "graph.microsoft.com"],
"mediaAuthAllowHosts": ["*.sharepoint.com", "*.graph.microsoft.com", "graph.microsoft.com"],
"sharePointSiteId": "<redacted-sharepoint-site-id>"
}Also tested with ["*"] for both allowHosts — same result.
Key observations
- The
graph media fetch emptylog does not include the{ attempts }metadata in the structured log output, making it hard to see HTTP status codes - The entire graph fallback path completes in ~400ms (receive → empty result), which is consistent with a token + fetch actually happening
- File sending via SharePoint works correctly after configuring
sharePointSiteId - The issue affects both DM and channel file attachments
- Bot Framework activity.id matches Graph message ID (e.g.,
<redacted-msg-id>)
Likely cause
Something in the downloadMSTeamsGraphMedia function silently fails between the token acquisition and the final media result. The outer try/catch blocks in graph.ts (lines ~263 and ~333) swallow all errors:
} catch {
// Ignore message fetch failures.
}} catch {
// Ignore SharePoint download failures.
}This makes it impossible to diagnose whether the Graph message fetch fails, the SharePoint URL filtering rejects the attachment, or the shares API download fails.
Suggested fix
- Add error logging inside the catch blocks (at minimum log the error message)
- Include the
attemptsarray data in thegraph media fetch emptylog output - Consider adding a
debuglog before and after the SharePoint attachment extraction loop
Workaround
None found. Users can paste URLs instead of uploading files as a temporary workaround.