Skip to content

Fix meeting activity deserialization for Teams PascalCase payloads#198

Merged
lilyydu merged 10 commits into
mainfrom
copilot/fix-deserialization-issue
Jan 12, 2026
Merged

Fix meeting activity deserialization for Teams PascalCase payloads#198
lilyydu merged 10 commits into
mainfrom
copilot/fix-deserialization-issue

Conversation

Copilot AI commented Nov 5, 2025

Copy link
Copy Markdown
Contributor

Teams sends meeting start/end events with PascalCase properties in the value object (Id, MeetingType, Title, JoinUrl, StartTime, EndTime), causing deserialization failures.

Changes

  • Updated MeetingStartActivityValue and MeetingEndActivityValue to use PascalCase in JsonPropertyName attributes
  • Updated test fixtures to match actual Teams payload format
  • Added comprehensive tests validating serialization, deserialization, and polymorphic type handling:
    • Basic deserialization with Teams PascalCase payloads
    • Round-trip serialization/deserialization verification
    • Polymorphic deserialization as EventActivity base class
    • Polymorphic deserialization as IActivity interface

Example

{
  "name": "application/vnd.microsoft.meetingEnd",
  "type": "event",
  "value": {
    "Id": "MCMx...",           // Was: "id"
    "MeetingType": "Scheduled", // Was: "meetingType"
    "Title": "Daily Standup",   // Was: "title"
    "JoinUrl": "https://...",   // Was: "joinUrl"
    "EndTime": "2025-10-31..."  // Was: "endTime"
  }
}

Testing

  • ✅ All 339 tests pass
  • ✅ 10 comprehensive PascalCase-specific tests added covering all scenarios
  • ✅ Serialization produces correct PascalCase format
  • ✅ Round-trip serialization/deserialization verified

This deviates from the library's camelCase convention but matches the actual Teams platform format.

Original prompt

This section details on the original issue you should resolve

<issue_title>Exception while deserializing Activity when meeting starts or ends - because of case sensitivity</issue_title>
<issue_description>When meeting starts or ends, library crashes while deserializing JSON to activity. Deep inside Activity Json Converter.
I get this JSON from Teams:

{
    "name": "application/vnd.microsoft.meetingEnd",
    "type": "event",
    "timestamp": "2025-10-31T11:38:15.5375726Z",
    "id": "1761910695513",
    "channelId": "msteams",
    "serviceUrl": "https://smba.trafficmanager.net/emea/167c22a9-1b2e-439c-ad74-cc77e9e118d8/",
    "from": {
        "id": "29:1geTNfcvfJus0De5z4gr7HeHGMOuln9LY8aHFGtwBqhOl7ZYQFcM2CL1ODjhgHE1XTq3vBeeRlGGGPvFWi0BzRw",
        "name": "",
        "aadObjectId": "86a23cfc-f78e-424a-8947-7ae0ce242da1"
    },
    "conversation": {
        "isGroup": true,
        "conversationType": "groupChat",
        "tenantId": "167c22a9-1b2e-439c-ad74-cc77e9e118d8",
        "id": "19:meeting_MTRmMTQ5NDYtMTYyYi00NmNlLWI4ZTQtN2I1MTYzM2RkYTg3@thread.v2"
    },
    "recipient": {
        "id": "28:c9a052ed-f68c-4227-b081-01da0669c49c",
        "name": "teams-bot"
    },
    "entities": [
        {
            "locale": "en-US",
            "country": "US",
            "type": "clientInfo"
        }
    ],
    "channelData": {
        "tenant": {
            "id": "167c22a9-1b2e-439c-ad74-cc77e9e118d8"
        },
        "source": null,
        "meeting": {
            "id": "MCMxOTptZWV0aW5nX01UUm1NVFE1TkRZdE1UWXlZaTAwTm1ObExXSTRaVFF0TjJJMU1UWXpNMlJrWVRnM0B0aHJlYWQudjIjMA=="
        }
    },
    "value": {
        "MeetingType": "Scheduled",
        "Title": "asdasd",
        "Id": "MCMxOTptZWV0aW5nX01UUm1NVFE1TkRZdE1UWXlZaTAwTm1ObExXSTRaVFF0TjJJMU1UWXpNMlJrWVRnM0B0aHJlYWQudjIjMA==",
        "JoinUrl": "https://teams.microsoft.com/l/meetup-join/19%3ameeting_MTRmMTQ5NDYtMTYyYi00NmNlLWI4ZTQtN2I1MTYzM2RkYTg3%40thread.v2/0?context=%7b%22Tid%22%3a%22167c22a9-1b2e-439c-ad74-cc77e9e118d8%22%2c%22Oid%22%3a%2286a23cfc-f78e-424a-8947-7ae0ce242da1%22%7d",
        "EndTime": "2025-10-31T11:38:15.5375726Z"
    },
    "locale": "en-US"
}

Look at casing. Every property is in lower case BUT value object properties which are in upper case.

Thus JsonConverter throws an error:

'JSON deserialization for type 'Microsoft.Teams.Api.Activities.Events.MeetingEndActivityValue' was missing required properties including: 'id', 'meetingType', 'joinUrl', 'title', 'endTime'.'

It's completely blockers. Do you have any fast workaround?
</issue_description>

<agent_instructions>update the meetings types in the Microsoft.Teams.Api package to be PascalCase instead of CamelCase when serializing/deserializing to/from JSON (ie via JsonPropertyNameAttribute).</agent_instructions>

Comments on the Issue (you are @copilot in this section)

@aacebo thanks for the report, I'm reaching out to our platform team to figure out why they are sending the payload in this format, to our knowledge this is the incorrect format using pascal case instead of camel case.

💬 We'd love your input! Share your thoughts on Copilot coding agent in our 2 minute survey.

Copilot AI changed the title [WIP] Fix exception during Activity deserialization on meeting events Fix meeting activity deserialization for Teams PascalCase payloads Nov 5, 2025
Copilot AI requested a review from aacebo November 5, 2025 18:27
@aacebo

aacebo commented Nov 5, 2025

Copy link
Copy Markdown
Collaborator

I attest that I have verified

@aacebo
aacebo marked this pull request as ready for review November 5, 2025 19:40
heyitsaamir
heyitsaamir previously approved these changes Nov 6, 2025

@heyitsaamir heyitsaamir left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not blocking, but this seems like a miss from their end..... why would they adopt this deviation from the norm.... Could be worth asking in TeamSid....

@heyitsaamir

Copy link
Copy Markdown
Collaborator

Also pls raise PRs in the other repos too 🙏🏽

@rido-min

rido-min commented Nov 6, 2025

Copy link
Copy Markdown
Contributor

was this working before? wondering if different Teams client versions, or Rings, might use camelCase for these.

We should have a confirmation from backend folks that this is the expected casing.

@aacebo

aacebo commented Nov 7, 2025

Copy link
Copy Markdown
Collaborator

@rido-min pinged you in teams with the confirmation thread, also confirmed via BF types that its historically been in Pascal case for some reason... not happy about it but platform can't change it cause that would break people @heyitsaamir https://github.com/microsoft/botbuilder-dotnet/blob/main/libraries/Microsoft.Bot.Schema/Teams/MeetingEventDetails.cs#L46
https://github.com/microsoft/botbuilder-dotnet/blob/main/libraries/Microsoft.Bot.Schema/Teams/MeetingStartEventDetails.cs#L48

@aacebo
aacebo requested a review from rido-min November 7, 2025 15:28
@AdamJachocki

Copy link
Copy Markdown

When it will be fixed? It's blocker for me as stated here: #196

@aacebo

aacebo commented Nov 18, 2025

Copy link
Copy Markdown
Collaborator

@AdamJachocki sorry for the wait, we are just creating a sample and verifying the change with our backend team before merging and releasing a fix for this. Thank you for your patience!

@aacebo

aacebo commented Dec 10, 2025

Copy link
Copy Markdown
Collaborator

@copilot add some new tests to Microsoft.Teams.Api.Tests to ensure the changes work. Be sure to follow the same style as the tests that already exist

Copilot AI commented Dec 10, 2025

Copy link
Copy Markdown
Contributor Author

@copilot add some new tests to Microsoft.Teams.Api.Tests to ensure the changes work. Be sure to follow the same style as the tests that already exist

Added 6 new comprehensive tests following the existing test patterns:

MeetingEndActivity (3 new tests):

  • MeetingEndActivity_JsonSerialize_PascalCase_RoundTrip - Verifies serialization produces PascalCase and round-trip works
  • MeetingEndActivity_JsonDeserialize_TeamsPayload_As_EventActivity - Tests polymorphic deserialization as EventActivity
  • MeetingEndActivity_JsonDeserialize_TeamsPayload_As_IActivity - Tests polymorphic deserialization as IActivity

MeetingStartActivity (3 new tests):

  • MeetingStartActivity_JsonSerialize_PascalCase_RoundTrip - Verifies serialization produces PascalCase and round-trip works
  • MeetingStartActivity_JsonDeserialize_TeamsPayload_As_EventActivity - Tests polymorphic deserialization as EventActivity
  • MeetingStartActivity_JsonDeserialize_TeamsPayload_As_IActivity - Tests polymorphic deserialization as IActivity

All 339 tests pass. Commit: 7d87077

@AdamJachocki

Copy link
Copy Markdown

When it will be finally fixed? It lasts for more than 5 weeks already!

lilyydu
lilyydu previously approved these changes Jan 6, 2026
heyitsaamir
heyitsaamir previously approved these changes Jan 7, 2026
@lilyydu
lilyydu dismissed stale reviews from heyitsaamir and themself via 285efff January 7, 2026 23:45
@rajan-chari

Copy link
Copy Markdown
Contributor

Ready for Review and Merge

This PR successfully fixes issue #196 by updating the meeting activity value properties to use PascalCase in JsonPropertyName attributes, matching the actual Teams platform payload format.

Summary of Changes

Core Fix: Updated MeetingStartActivityValue and MeetingEndActivityValue to use PascalCase:

  • "id""Id"
  • "meetingType""MeetingType"
  • "joinUrl""JoinUrl"
  • "title""Title"
  • "startTime""StartTime"
  • "endTime""EndTime"

Tests: Added comprehensive test coverage (10 new tests)

  • Basic deserialization with Teams PascalCase payloads
  • Round-trip serialization/deserialization verification
  • Polymorphic deserialization scenarios

Sample: Added Samples.Meetings demonstrating the fix

CI Status: All checks passing

  • Build & Test & Lint: ✅ Pass
  • CodeQL Analysis: ✅ Pass
  • CLA Check: ✅ Pass

Platform Confirmation

As confirmed by @aacebo, the Teams platform team has verified that PascalCase is the correct and historical format for these events, matching the Bot Framework types.

Impact

This is a critical blocker fix that enables proper deserialization of meeting start/end events from Teams. Multiple users are waiting for this fix (see comments from @AdamJachocki).

@lilyydu @heyitsaamir - This PR is ready for review and merge. All tests pass, the fix is verified, and platform has confirmed the format. Please review and merge when ready.

@lilyydu

lilyydu commented Jan 9, 2026

Copy link
Copy Markdown
Contributor

Tested and verified

image

lilyydu
lilyydu previously approved these changes Jan 9, 2026
heyitsaamir
heyitsaamir previously approved these changes Jan 10, 2026
rido-min
rido-min previously approved these changes Jan 12, 2026

@rido-min rido-min left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, I tested and everything works as expected (after dealing with TDP issues)

the only nit is that the new sample should be added to the solution

@lilyydu
lilyydu dismissed stale reviews from rido-min, heyitsaamir, and themself via 550a4da January 12, 2026 21:23
@lilyydu
lilyydu merged commit b026f9b into main Jan 12, 2026
6 of 7 checks passed
@lilyydu
lilyydu deleted the copilot/fix-deserialization-issue branch January 12, 2026 21:35
@lilyydu lilyydu self-assigned this Jan 13, 2026
lilyydu added a commit to microsoft/teams.ts that referenced this pull request Jan 22, 2026
lilyydu added a commit to microsoft/teams.py that referenced this pull request Jan 27, 2026
ShanmathiMayuramKrithivasan pushed a commit to ShanmathiMayuramKrithivasan/teams.net that referenced this pull request Mar 10, 2026
…icrosoft#198)

Teams sends meeting start/end events with PascalCase properties in the
`value` object (`Id`, `MeetingType`, `Title`, `JoinUrl`, `StartTime`,
`EndTime`), causing deserialization failures.

### Changes
- Updated `MeetingStartActivityValue` and `MeetingEndActivityValue` to
use PascalCase in `JsonPropertyName` attributes
- Updated test fixtures to match actual Teams payload format
- Added comprehensive tests validating serialization, deserialization,
and polymorphic type handling:
  - Basic deserialization with Teams PascalCase payloads
  - Round-trip serialization/deserialization verification
  - Polymorphic deserialization as `EventActivity` base class
  - Polymorphic deserialization as `IActivity` interface

### Example
```json
{
  "name": "application/vnd.microsoft.meetingEnd",
  "type": "event",
  "value": {
    "Id": "MCMx...",           // Was: "id"
    "MeetingType": "Scheduled", // Was: "meetingType"
    "Title": "Daily Standup",   // Was: "title"
    "JoinUrl": "https://...",   // Was: "joinUrl"
    "EndTime": "2025-10-31..."  // Was: "endTime"
  }
}
```

### Testing
- ✅ All 339 tests pass
- ✅ 10 comprehensive PascalCase-specific tests added covering all
scenarios
- ✅ Serialization produces correct PascalCase format
- ✅ Round-trip serialization/deserialization verified

This deviates from the library's camelCase convention but matches the
actual Teams platform format.

<!-- START COPILOT CODING AGENT SUFFIX -->



<details>

<summary>Original prompt</summary>

> 
> ----
> 
> *This section details on the original issue you should resolve*
> 
> <issue_title>Exception while deserializing Activity when meeting
starts or ends - because of case sensitivity</issue_title>
> <issue_description>When meeting starts or ends, library crashes while
deserializing JSON to activity. Deep inside Activity Json Converter.
> I get this JSON from Teams:
> 
> ```
> {
>     "name": "application/vnd.microsoft.meetingEnd",
>     "type": "event",
>     "timestamp": "2025-10-31T11:38:15.5375726Z",
>     "id": "1761910695513",
>     "channelId": "msteams",
> "serviceUrl":
"https://smba.trafficmanager.net/emea/167c22a9-1b2e-439c-ad74-cc77e9e118d8/",
>     "from": {
> "id":
"29:1geTNfcvfJus0De5z4gr7HeHGMOuln9LY8aHFGtwBqhOl7ZYQFcM2CL1ODjhgHE1XTq3vBeeRlGGGPvFWi0BzRw",
>         "name": "",
>         "aadObjectId": "86a23cfc-f78e-424a-8947-7ae0ce242da1"
>     },
>     "conversation": {
>         "isGroup": true,
>         "conversationType": "groupChat",
>         "tenantId": "167c22a9-1b2e-439c-ad74-cc77e9e118d8",
> "id":
"19:meeting_MTRmMTQ5NDYtMTYyYi00NmNlLWI4ZTQtN2I1MTYzM2RkYTg3@thread.v2"
>     },
>     "recipient": {
>         "id": "28:c9a052ed-f68c-4227-b081-01da0669c49c",
>         "name": "teams-bot"
>     },
>     "entities": [
>         {
>             "locale": "en-US",
>             "country": "US",
>             "type": "clientInfo"
>         }
>     ],
>     "channelData": {
>         "tenant": {
>             "id": "167c22a9-1b2e-439c-ad74-cc77e9e118d8"
>         },
>         "source": null,
>         "meeting": {
> "id":
"MCMxOTptZWV0aW5nX01UUm1NVFE1TkRZdE1UWXlZaTAwTm1ObExXSTRaVFF0TjJJMU1UWXpNMlJrWVRnM0B0aHJlYWQudjIjMA=="
>         }
>     },
>     "value": {
>         "MeetingType": "Scheduled",
>         "Title": "asdasd",
> "Id":
"MCMxOTptZWV0aW5nX01UUm1NVFE1TkRZdE1UWXlZaTAwTm1ObExXSTRaVFF0TjJJMU1UWXpNMlJrWVRnM0B0aHJlYWQudjIjMA==",
> "JoinUrl":
"https://teams.microsoft.com/l/meetup-join/19%3ameeting_MTRmMTQ5NDYtMTYyYi00NmNlLWI4ZTQtN2I1MTYzM2RkYTg3%40thread.v2/0?context=%7b%22Tid%22%3a%22167c22a9-1b2e-439c-ad74-cc77e9e118d8%22%2c%22Oid%22%3a%2286a23cfc-f78e-424a-8947-7ae0ce242da1%22%7d",
>         "EndTime": "2025-10-31T11:38:15.5375726Z"
>     },
>     "locale": "en-US"
> }
> ```
> 
> Look at casing. Every property is in lower case BUT **value** object
properties which are in upper case.
> 
> Thus JsonConverter throws an error:
> 
> `'JSON deserialization for type
'Microsoft.Teams.Api.Activities.Events.MeetingEndActivityValue' was
missing required properties including: 'id', 'meetingType', 'joinUrl',
'title', 'endTime'.'`
> 
> It's completely blockers. Do you have any fast workaround?
> </issue_description>
> 
> <agent_instructions>update the meetings types in the
`Microsoft.Teams.Api` package to be PascalCase instead of CamelCase when
serializing/deserializing to/from JSON (ie via
`JsonPropertyNameAttribute`).</agent_instructions>
> 
> ## Comments on the Issue (you are @copilot in this section)
> 
> <comments>
> <comment_new><author>@aacebo</author><body>
> thanks for the report, I'm reaching out to our platform team to figure
out why they are sending the payload in this format, to our knowledge
this is the incorrect format using pascal case instead of camel
case.</body></comment_new>
> </comments>
> 


</details>

- Fixes microsoft#196

<!-- START COPILOT CODING AGENT TIPS -->
---

💬 We'd love your input! Share your thoughts on Copilot coding agent in
our [2 minute survey](https://gh.io/copilot-coding-agent-survey).

---------

Co-authored-by: copilot-swe-agent[bot] <[email protected]>
Co-authored-by: aacebo <[email protected]>
Co-authored-by: Alex Acebo <[email protected]>
Co-authored-by: Lily Du <[email protected]>
Co-authored-by: lilydu <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Exception while deserializing Activity when meeting starts or ends - because of case sensitivity

7 participants