Skip to content

bug(msteams): DM inline images and file attachments silently dropped #65329

@anhntservices-1808

Description

@anhntservices-1808

Summary

When a user sends an image (inline paste/screenshot) or file attachment via Teams personal DM, the bot receives a msteams://media/... placeholder that is never resolved. The attachment content is silently dropped — no error is shown to the user and no meaningful log is emitted.

Environment

  • OpenClaw version: 2026.4.10
  • Channel: msteams (personal DM / personal scope)
  • Manifest: supportsFiles: true, scopes include personal
  • Graph API permissions: not configured (RSC only)

Steps to Reproduce

  1. Configure OpenClaw with msteams (RSC only, no Graph API)
  2. Open a personal DM with the bot in Teams
  3. Send an image by pasting/screenshot (inline) OR attach a file via the paperclip button
  4. Bot receives message but cannot access the attachment content

Expected Behavior

Docs state:

DMs: Images and file attachments work via Teams bot file APIs.
With Teams RSC only: Receive personal (DM) file attachments ✅

Attachment should be downloaded and passed to the agent.

Actual Behavior

Agent receives msteams://media/{messageId}/0 as a placeholder. The image tool rejects it:

Unsupported image reference: msteams://media/1775970156765/0.
Use a file path, a file:// URL, a data: URL, or an http(s) URL.

With logging.level: debug, zero media-related debug logs are emitted — the failure is completely silent.

Root Cause Analysis (code)

In resolveMSTeamsInboundMedia, there are 3 download paths:

Path 1 – Direct URL download (downloadMSTeamsAttachments): Tries contentUrl on the attachment object. Fails silently for inline images in DMs.

Path 2 – Bot Framework attachment download (DM fallback):

if (hasHtmlAttachment && isBotFrameworkPersonalChatId(conversationId))

Only runs when hasHtmlAttachment = true. Inline images sent directly do not include an HTML wrapper, so this condition is never met.

Path 3 – Graph API download (channel/group fallback):

if (hasHtmlAttachment && mediaList.length === 0 && !isBotFrameworkPersonalChatId(conversationId))

Explicitly excluded for personal DMs via !isBotFrameworkPersonalChatId.

Result: all 3 paths fail/skip for inline images in DMs → media dropped silently.

Related

Suggested Fix

For DMs (isBotFrameworkPersonalChatId = true), when Path 1 fails:

  1. Attempt Bot Framework attachment download regardless of hasHtmlAttachment (Path 2 without the HTML gate), OR
  2. Allow Graph API fallback for DMs using the already-resolved graphConversationId from resolveGraphChatId (Path 3 without !isBotFrameworkPersonalChatId)

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions