-
-
Notifications
You must be signed in to change notification settings - Fork 69.5k
fix(msteams): FileConsent upload succeeds but FileInfoCard fails — TurnContext proxy revoked #29847
Description
Bug Description
When sending files via FileConsentCard in a Teams DM, the file uploads to OneDrive successfully, but the FileInfoCard (download card) never appears in the chat. The user clicks "Allow", nothing visibly happens, and the file is silently uploaded to OneDrive without any chat confirmation.
Root Cause
In extensions/msteams/src/monitor-handler.ts, the handler.run function handles file consent invokes:
handler.run = async (context: unknown) => {
const ctx = context as MSTeamsTurnContext;
if (ctx.activity?.type === "invoke" && ctx.activity?.name === "fileConsent/invoke") {
await ctx.sendActivity({ type: "invokeResponse", value: { status: 200 } });
handleFileConsentInvoke(ctx, deps.log).catch(...);
return; // handler returns → webhook response sent → TurnContext proxy revoked
}
};- Invoke response is sent immediately ✅
handleFileConsentInvokeis called (fire-and-forget)- Handler returns → webhook HTTP response completes → TurnContext proxy is revoked by the SDK
- Inside
handleFileConsentInvoke:uploadToConsentUrl()succeeds (uses plainfetch, no context needed) ✅context.sendActivity(fileInfoCard)fails ❌ — proxy revoked
Error: TypeError: Cannot perform 'get' on a proxy that has been revoked
Expected Behavior
After the user clicks "Allow":
- File uploads to OneDrive
FileInfoCardappears in the chat with a download link- User can click to download the file
Actual Behavior
After the user clicks "Allow":
- File uploads to OneDrive ✅
- FileInfoCard never appears in chat ❌
- User sees nothing — appears broken
Attempted Fixes
- Await the handler (keep upload synchronous) — context still revoked because invoke response was already sent
setImmediateasync — same proxy revocationadapter.continueConversation(ref, callback)—Invalid conversation reference objectadapter.continueConversation(appId, ref, callback)— same invalid ref error
Suggested Fix
The handleFileConsentInvoke function needs access to the proactive messaging dependencies (adapter, appId, conversationStore) so it can send the FileInfoCard via proactive messaging after the upload completes — the same path that send.ts uses for regular proactive messages.
// Pass proactive messaging deps to handler
handleFileConsentInvoke(ctx, deps.log, {
adapter: deps.adapter,
appId: deps.appId,
conversationStore: deps.conversationStore,
}).catch(...);
// Inside handleFileConsentInvoke, after upload:
const ref = await conversationStore.get(conversationId);
await adapter.continueConversation(appId, ref, async (proactiveCtx) => {
await proactiveCtx.sendActivity({ type: "message", attachments: [fileInfoCard] });
});Environment
- OpenClaw: 2026.2.26
- Plugin: @openclaw/msteams
- @microsoft/agents-hosting: 1.3.x
- Bot type: Single Tenant
- Teams client: Desktop (macOS) and Web
- Chat type: Personal (1:1 DM)
- File size: 55 bytes (timing is not the issue — upload takes <1 second)
Related
- Same TurnContext proxy revocation issue affects long-running agent replies (msteams provider exits immediately, causing infinite auto-restart loop #27885)
- PR fix(msteams): block provider promise until abort signal fires #27968 fixes the monitor keep-alive but not this file consent issue