From 09f4abdd61c86afac9dc61f32d3be1257a656b0d Mon Sep 17 00:00:00 2001 From: AI Assistant Date: Thu, 26 Feb 2026 22:42:34 +0800 Subject: [PATCH] fix(msteams): Send invokeResponse immediately to prevent Teams timeout (#27632) Fix file upload 'Something went wrong' error by sending the invoke acknowledgement before performing the file upload, rather than after. Changes: - Move invokeResponse to fire immediately upon receiving fileConsent/invoke - Handle file upload asynchronously without blocking the response - Update test to wait for async upload completion using vi.waitFor This prevents Teams from timing out while waiting for the HTTP 200 acknowledgement during slow file uploads to OneDrive. Fixes #27632 --- .../src/monitor-handler.file-consent.test.ts | 18 ++++++++++++------ extensions/msteams/src/monitor-handler.ts | 14 ++++++++------ 2 files changed, 20 insertions(+), 12 deletions(-) diff --git a/extensions/msteams/src/monitor-handler.file-consent.test.ts b/extensions/msteams/src/monitor-handler.file-consent.test.ts index 804ce58107c..8223bb3e95d 100644 --- a/extensions/msteams/src/monitor-handler.file-consent.test.ts +++ b/extensions/msteams/src/monitor-handler.file-consent.test.ts @@ -148,18 +148,24 @@ describe("msteams file consent invoke authz", () => { await handler.run?.(context); - expect(fileConsentMockState.uploadToConsentUrl).toHaveBeenCalledTimes(1); + // invokeResponse should be sent immediately + expect(sendActivity).toHaveBeenCalledWith( + expect.objectContaining({ + type: "invokeResponse", + }), + ); + + // Wait for async upload to complete + await vi.waitFor(() => { + expect(fileConsentMockState.uploadToConsentUrl).toHaveBeenCalledTimes(1); + }); + expect(fileConsentMockState.uploadToConsentUrl).toHaveBeenCalledWith( expect.objectContaining({ url: "https://upload.example.com/put", }), ); expect(getPendingUpload(uploadId)).toBeUndefined(); - expect(sendActivity).toHaveBeenCalledWith( - expect.objectContaining({ - type: "invokeResponse", - }), - ); }); it("rejects cross-conversation accept invoke and keeps pending upload", async () => { diff --git a/extensions/msteams/src/monitor-handler.ts b/extensions/msteams/src/monitor-handler.ts index 086b82d496a..6a7d6a47c11 100644 --- a/extensions/msteams/src/monitor-handler.ts +++ b/extensions/msteams/src/monitor-handler.ts @@ -143,12 +143,14 @@ export function registerMSTeamsHandlers( const ctx = context as MSTeamsTurnContext; // Handle file consent invokes before passing to normal flow if (ctx.activity?.type === "invoke" && ctx.activity?.name === "fileConsent/invoke") { - const handled = await handleFileConsentInvoke(ctx, deps.log); - if (handled) { - // Send invoke response for file consent - await ctx.sendActivity({ type: "invokeResponse", value: { status: 200 } }); - return; - } + // Send invoke response IMMEDIATELY to prevent Teams timeout + await ctx.sendActivity({ type: "invokeResponse", value: { status: 200 } }); + + // Handle file upload asynchronously (don't await) + handleFileConsentInvoke(ctx, deps.log).catch((err) => { + deps.log.debug?.("file consent handler error", { error: String(err) }); + }); + return; } return originalRun.call(handler, context); };