Teams client builds a five part bot member MRI (28:{botId}:appId:{teamsAppId}) and the chat service rejects it with "Invalid member MRI format"

Mustapha Ben Chaaben 0 Reputation points
2026-08-03T16:50:37.0033333+00:00

Summary

When a user opens our line of business bot through the Teams client's own Search or New chat surface, the client composes a member MRI with five colon separated parts. The Teams chat service then rejects that identifier as malformed, and messages typed into the resulting conversation fail to send. Microsoft documents exactly one bot member MRI form, the two part 28:<botId>. The string the client generates corresponds to nothing in the published format.

The producer of the identifier and the component that rejects it are both first party. Our app supplies a manifest. It does not compose member MRIs and it does not decide what the search surface hands to the chat service.

Environment

Item Value
Product Microsoft Teams, web and desktop client
-------- --------
Product Microsoft Teams, web and desktop client
App type Custom line of business app, single tenant
App version 0.1.5
First observed 22 July 2026

Tenant ID, user object ID, bot App ID, Teams catalog app ID and manifest external ID are withheld from this post and supplied on request. Placeholders below stand for real GUIDs. The same placeholder always means the same value.

Steps to reproduce

  1. Sign in to Teams as a user who has the app installed.
  2. Open Search or New chat and type the app's display name.
  3. Two identical results appear for the app, though the user holds a single installation.
  4. Select a result to open the personal bot chat.
  5. Type any message and press Send.

Observed result

The client composes this member MRI, with the two GUIDs replaced by placeholders:

28:<bot-app-id>:appId:<teams-catalog-app-id>

Both are standard 36 character GUIDs. The literal string :appId: sits between them.

The chat service rejects it:

errorCode: 201
errorSubCode: 1
Invalid member MRI format: >3 parts split by ':'

The message is marked "Failed to send" in the composer, with retry and delete controls beside it. Screenshot attached.

Expected result

The client composes a member MRI the chat service accepts, and the message sends.

What Microsoft Graph already confirms

Microsoft support asked for these checks before routing the case here. All three came back clean.

GET /users/{user-id}/teamwork/installedApps?$expand=teamsAppDefinition($expand=bot) returns exactly one installation of the app for the affected user, and its bot resolves to a single bot object whose id matches the bot App ID declared in the manifest exactly.

GET /users/{user-id}/teamwork/installedApps/{installationId}/chat returns a valid one on one chat, chatType: oneOnOne, isHiddenForAllMembers: false.

Opening that Graph provided webUrl while signed in as the affected user loads the existing bot conversation with full history, and renders the composer and Send control without error.

No Graph call in this case fails.

What that rules out

There is no duplicate installation, the installed app maps to the correct bot, and the personal chat object exists and is reachable. The customer side explanations for a broken bot chat do not hold. The failure sits in how the Teams client resolves a bot identity from its search surface, or in the server side data that surface reads.

What I have not established

I have not sent a message through the Graph resolved chat, only opened it. Opening a chat is a read. Whether that path accepts a write is untested, so I make no claim that it is a working workaround.

I have not queried the tenant app catalog. The checks above cover installedApps, which is a user to app link, not appCatalogs/teamsApps, which is what the search surface reads.

Likely cause, unconfirmed

The duplicate search result is the one detail nothing else accounts for. A single installed app producing two identical entries in Search is server side data, and nothing in a tenant app can write a second entry there.

If one bot ID resolves to more than one catalog entry, the search layer has to indicate which entry the user selected, and appending the catalog teamsAppId to the bot MRI is an obvious way to do it. That produces exactly the observed five part string, and exactly the string the chat service was never built to parse. Graph makes this state easy to reach without noticing, since teamsApp.id is server generated while the manifest id is stamped as externalId, so uploading one package by two routes creates two catalog IDs for one bot with nothing in the installation list to show for it.

This fits every observed fact, including the clean installation check. It is unproven until I run the catalog query.

Questions

  1. Is 28:{botId}:appId:{teamsAppId} a documented or supported member MRI form? The deep link reference publishes only the two part 28:<botId>, and the chat service error indicates it accepts at most three parts.
  2. Under what conditions does the client append :appId:{teamsAppId} to a bot MRI? If it is disambiguation between catalog entries, why is the result an identifier the chat service rejects?
  3. Is a single bot present in more than one tenant catalog entry, for example sideloaded alongside organization published, a supported state? If it is, the client resolving it into a malformed identifier looks like a defect. If it is not, that constraint does not appear to be documented.
  4. Is the correct guidance that bots should never be opened through Search or New chat, and that products should ship the documented two part deep link instead? If so, that is worth stating explicitly in the bot deployment documentation.

I searched Microsoft Q&A, Microsoft Learn, Stack Overflow, and the MicrosoftDocs/msteams-docs and OfficeDev/Microsoft-Teams-Samples repositories before posting. The error string and the five part MRI shape return no public hits.

Happy to supply the full identifier set, an in client Report a problem feedback ID, or a fresh reproduction on request.

Body

Summary

When a user opens our line of business bot through the Teams client's own Search or New chat surface, the client composes a member MRI with five colon separated parts. The Teams chat service then rejects that identifier as malformed, and messages typed into the resulting conversation fail to send. Microsoft documents exactly one bot member MRI form, the two part 28:<botId>. The string the client generates corresponds to nothing in the published format.

The producer of the identifier and the component that rejects it are both first party. Our app supplies a manifest. It does not compose member MRIs and it does not decide what the search surface hands to the chat service.

Environment

Item Value
Product Microsoft Teams, web and desktop client
App type Custom line of business app, single tenant
App version 0.1.5
First observed 22 July 2026

Tenant ID, user object ID, bot App ID, Teams catalog app ID and manifest external ID are withheld from this post and supplied on request. Placeholders below stand for real GUIDs. The same placeholder always means the same value.

Steps to reproduce

  1. Sign in to Teams as a user who has the app installed.
  2. Open Search or New chat and type the app's display name.
  3. Two identical results appear for the app, though the user holds a single installation.
  4. Select a result to open the personal bot chat.
  5. Type any message and press Send.

Observed result

The client composes this member MRI, with the two GUIDs replaced by placeholders:

28:<bot-app-id>:appId:<teams-catalog-app-id>

Both are standard 36 character GUIDs. The literal string :appId: sits between them.

The chat service rejects it:

errorCode: 201
errorSubCode: 1
Invalid member MRI format: >3 parts split by ':'

The message is marked "Failed to send" in the composer, with retry and delete controls beside it. Screenshot attached.

Expected result

The client composes a member MRI the chat service accepts, and the message sends.

What Microsoft Graph already confirms

Microsoft support asked for these checks before routing the case here. All three came back clean.

GET /users/{user-id}/teamwork/installedApps?$expand=teamsAppDefinition($expand=bot) returns exactly one installation of the app for the affected user, and its bot resolves to a single bot object whose id matches the bot App ID declared in the manifest exactly.

GET /users/{user-id}/teamwork/installedApps/{installationId}/chat returns a valid one on one chat, chatType: oneOnOne, isHiddenForAllMembers: false.

Opening that Graph provided webUrl while signed in as the affected user loads the existing bot conversation with full history, and renders the composer and Send control without error.

No Graph call in this case fails.

What that rules out

There is no duplicate installation, the installed app maps to the correct bot, and the personal chat object exists and is reachable. The customer side explanations for a broken bot chat do not hold. The failure sits in how the Teams client resolves a bot identity from its search surface, or in the server side data that surface reads.

What I have not established

I have not sent a message through the Graph resolved chat, only opened it. Opening a chat is a read. Whether that path accepts a write is untested, so I make no claim that it is a working workaround.

I have not queried the tenant app catalog. The checks above cover installedApps, which is a user to app link, not appCatalogs/teamsApps, which is what the search surface reads.

Likely cause, unconfirmed

The duplicate search result is the one detail nothing else accounts for. A single installed app producing two identical entries in Search is server side data, and nothing in a tenant app can write a second entry there.

If one bot ID resolves to more than one catalog entry, the search layer has to indicate which entry the user selected, and appending the catalog teamsAppId to the bot MRI is an obvious way to do it. That produces exactly the observed five part string, and exactly the string the chat service was never built to parse. Graph makes this state easy to reach without noticing, since teamsApp.id is server generated while the manifest id is stamped as externalId, so uploading one package by two routes creates two catalog IDs for one bot with nothing in the installation list to show for it.

This fits every observed fact, including the clean installation check. It is unproven until I run the catalog query.

Questions

  1. Is 28:{botId}:appId:{teamsAppId} a documented or supported member MRI form? The deep link reference publishes only the two part 28:<botId>, and the chat service error indicates it accepts at most three parts.
  2. Under what conditions does the client append :appId:{teamsAppId} to a bot MRI? If it is disambiguation between catalog entries, why is the result an identifier the chat service rejects?
  3. Is a single bot present in more than one tenant catalog entry, for example sideloaded alongside organization published, a supported state? If it is, the client resolving it into a malformed identifier looks like a defect. If it is not, that constraint does not appear to be documented.
  4. Is the correct guidance that bots should never be opened through Search or New chat, and that products should ship the documented two part deep link instead? If so, that is worth stating explicitly in the bot deployment documentation.

I searched Microsoft Q&A, Microsoft Learn, Stack Overflow, and the MicrosoftDocs/msteams-docs and OfficeDev/Microsoft-Teams-Samples repositories before posting. The error string and the five part MRI shape return no public hits.

Happy to supply the full identifier set, an in client Report a problem feedback ID, or a fresh reproduction on request.

Microsoft Teams | Microsoft Teams for business | Other
0 comments No comments

2 answers

Sort by: Most helpful
  1. Mustapha Ben Chaaben 0 Reputation points
    2026-08-03T19:10:00.58+00:00

    Thanks for the detailed reply.

    Two corrections to my original post.

    First, I reinstalled the app. The duplicate search results are gone and the issue still happens, so the duplicate catalog entry theory in my post does not hold. The five part MRI is being generated with a single catalog entry present, which means it is not disambiguation between two entries.

    Second, the failure is intermittent rather than constant, but not randomly so. It goes a while without occurring, then once it starts it fails on every attempt in a row.

    My sense is that this is cached identity resolution. If the client resolves the bot once per session and caches the result, a session that resolved to the five part form would fail every send until that cache is rebuilt. That matches the pattern.

    Worth noting: when the send fails, nothing reaches our bot messaging endpoint. No activity at all. The message is rejected inside the Teams chat service, so none of our code runs on that path.

    I've attached a screenshot of how it looks on the client side when it fails. And it's associated with the API call failure I've mentioned before.

    Screenshot 2026-07-21 at 10.32.21 AM

    Was this answer helpful?


  2. Michelle Nguyen 340 Reputation points Independent Advisor
    2026-08-03T17:05:45.26+00:00

    Hi @Mustapha Ben Chaaben

    Thank you for the detailed investigation and for documenting the behavior so thoroughly. The information you've provided, particularly the malformed MRI value, the duplicate Search/New chat entries, and the Graph validation results, is extremely helpful.

    Based on the evidence shared, this does not appear to be caused by the bot implementation itself. Your Graph validation demonstrates that:

    • The user has a single installed instance of the app.
    • The installation resolves to the expected bot App ID.
    • A valid personal one-to-one chat already exists.
    • The chat can be opened successfully through the Graph-provided webUrl.

    Those findings significantly reduce the likelihood of a manifest, installation, or Bot Framework registration issue. Regarding your questions

    1. Is 28:{botId}:appId:{teamsAppId} a documented or supported member MRI format?

    At present, the publicly documented bot identifier format used in Teams deep links is: 28:<botId>

    I am not aware of any public documentation that describes:28:<botId>:appId:<teamsAppId>as a supported bot member MRI format.

    The error returned by the service: Invalid member MRI format: >3 parts split by ':'also appears consistent with the observation that the downstream service is not accepting the five-part identifier being supplied.

    1. Under what conditions is :appId:{teamsAppId} appended?

    Unfortunately, the internal resolution logic used by Teams Search and New Chat surfaces is not publicly documented. However, the behavior you've observed is noteworthy because:

    • Duplicate search results are being returned for what appears to be a single bot experience.
    • The generated MRI includes both the Bot App ID and a Teams catalog application identifier.
    • The resulting identifier is subsequently rejected by the chat service.

    That combination suggests a potential issue in the identity-resolution path used by the Search/New Chat experience. While your hypothesis regarding multiple catalog representations of the same bot is plausible, we cannot confirm it from the information currently available.

    1. Is a bot existing in multiple catalog entries a supported scenario?

    A Teams app can exist through multiple distribution mechanisms (for example, organizational publishing, updated package uploads, or sideloading during development). However, duplicate catalog representations should not result in a client generating an identifier that the messaging service cannot process.

    If multiple catalog records are involved in this case, the expected behavior would still be for Teams to resolve the conversation target correctly. The fact that the generated MRI is rejected suggests a potential product issue rather than an app-development issue.

    1. Should developers avoid Search/New Chat and rely only on deep links?

    No such guidance is currently documented. Search and New Chat are first-party Teams entry points and should support discovery and initiation of personal bot conversations. Developers should not be required to avoid those surfaces in order to achieve reliable messaging behavior.

    The documented deep-link approach remains a valid way to launch a bot conversation, but the behavior you're seeing through Search/New Chat would still warrant investigation if reproducible.

    Thank you again for the thorough write-up. The reproduction steps and Graph evidence provide a strong basis for further investigation.

    Was this answer helpful?

    0 comments No comments

Your answer

Answers can be marked as 'Accepted' by the question author and 'Recommended' by moderators, which helps users know the answer solved the author's problem.