Skip to content
🎉 Launch sale:50% off everything over $22 — automatically applied at checkout· ends Aug 2Shop the sale →
DevOps AI ToolKit
Newsletter
All guides
AI for Microsoft Teams By James Joyner IV · · 8 min read Last reviewed Jul 2026

Microsoft Teams Error: 'Request_MultipleObjectsWithSameKeyValue' — Cause, Fix, and Troubleshooting Guide

Quick answer

Fix Graph 400 Request_MultipleObjectsWithSameKeyValue in Teams: duplicate member/owner adds, repeated multivalued properties, and duplicate @odata.bind entries.

  • #microsoft-teams
  • #troubleshooting
  • #errors
  • #graph-api
Free toolkit

Stuck on this Microsoft Teams error? Get the free incident triage checklist

A one-page PDF — the exact steps to isolate, fix, and verify a production error like this one. No spam, unsubscribe anytime.

What this error means

Request_MultipleObjectsWithSameKeyValue is a Microsoft Graph directory error returned when a request would create two objects, or two references, that share a value on a property the directory treats as a key. In a Teams context you see it most often when adding a member or owner who is already on the team, when a request body repeats the same value in a multivalued property, or when a bulk create/update carries duplicate @odata.bind entries. Graph returns HTTP 400.

HTTP/1.1 400 Bad Request
Content-Type: application/json

{
  "error": {
    "code": "Request_MultipleObjectsWithSameKeyValue",
    "message": "Another object with the same value for property alternativeSecurityId already exists.",
    "innerError": {
      "date": "2026-07-12T11:04:09",
      "request-id": "5a1e77c9-2b6f-4c30-8a11-99aa77bb0033",
      "client-request-id": "5a1e77c9-2b6f-4c30-8a11-99aa77bb0033"
    }
  }
}

The message names the specific conflicting property, so it is your fastest signal for which value is duplicated. The general shape is always “Another object with the same value for property <name> already exists.”

What users report

  • Adding a team member or owner via POST /teams/{id}/members returns 400 with code Request_MultipleObjectsWithSameKeyValue.
  • A create-team or update call with an owners@odata.bind or members@odata.bind array fails when the same user is listed twice.
  • Re-running an “add these people” sync fails on the second run because the members already exist.
  • Adding a value to a multivalued property (for example a proxy address or a bound reference) fails because that value is already present.
  • The error names a property you did not set directly, because Graph derives the key from the object you referenced.
  • Some entries in a batch succeed and one 400s on the duplicate.

Tenant and app configuration causes

  • Member/owner already on the team. You are adding a user who is already a member (or already an owner) rather than checking first.
  • Duplicate value in the request body. The same user id or UPN appears twice in a members/owners array.
  • Duplicate @odata.bind reference. A create-team or PATCH lists the same directory object twice in a bind collection.
  • Repeated multivalued property value. You are appending a value that already exists on a multivalued attribute.
  • Non-idempotent sync. The job adds unconditionally instead of computing the set difference between desired and current membership.

Confirming tenant configuration

List current members and owners before you add anyone:

curl -s -X GET \
  "https://graph.microsoft.com/v1.0/teams/TEAM_ID/members?\$select=id,displayName,roles,userId" \
  -H "Authorization: Bearer $GRAPH_TOKEN" \
  | jq -r '.value[] | "\(.userId)\t\(.roles|join(","))\t\(.displayName)"'

Check whether a specific user is already present before adding:

USER_ID="aaaabbbb-cccc-dddd-eeee-ffff00001111"
curl -s -X GET \
  "https://graph.microsoft.com/v1.0/teams/TEAM_ID/members?\$select=userId" \
  -H "Authorization: Bearer $GRAPH_TOKEN" \
  | jq --arg u "$USER_ID" -e '[.value[].userId] | index($u) != null' \
  && echo "already a member"

Dedupe a request body before sending it. This catches the duplicate-@odata.bind case:

jq '.["members@odata.bind"] |= unique' team-create.json > team-create.deduped.json
diff <(jq '.["members@odata.bind"]|length' team-create.json) \
     <(jq '.["members@odata.bind"]|length' team-create.deduped.json)

Resolution

The reliable fix is to check membership first and only add users who are not already present. Compute the difference between desired and current membership, then add just the delta:

CURRENT=$(curl -s \
  "https://graph.microsoft.com/v1.0/teams/TEAM_ID/members?\$select=userId" \
  -H "Authorization: Bearer $GRAPH_TOKEN" | jq -r '.value[].userId')

for U in $(comm -23 <(sort desired-users.txt) <(echo "$CURRENT" | sort)); do
  curl -s -X POST \
    "https://graph.microsoft.com/v1.0/teams/TEAM_ID/members" \
    -H "Authorization: Bearer $GRAPH_TOKEN" -H "Content-Type: application/json" \
    -d "{
      \"@odata.type\": \"#microsoft.graph.aadUserConversationMember\",
      \"roles\": [],
      \"user@odata.bind\": \"https://graph.microsoft.com/v1.0/users('$U')\"
    }"
done

For create-team payloads, always unique the bind arrays before sending:

curl -s -X POST "https://graph.microsoft.com/v1.0/teams" \
  -H "Authorization: Bearer $GRAPH_TOKEN" -H "Content-Type: application/json" \
  -d @team-create.deduped.json

Make add-member idempotent: if the add returns 400 with code Request_MultipleObjectsWithSameKeyValue, treat it as already-satisfied rather than a failure, since the end state (user is a member) is what you wanted.

Avoiding tenant drift

  • Read before write. Always list current members/owners and add only the set difference; never add unconditionally.
  • Dedupe request bodies. Run unique on members@odata.bind and owners@odata.bind arrays before every create or PATCH.
  • Treat the 400 as idempotent-safe. Map this specific code to “already present” so retries and re-syncs do not fail the job.
  • Read the property name. The message tells you exactly which key collided — use it instead of guessing.
  • Watch UPN vs object id. Referencing the same user by UPN in one entry and object id in another can still collide — normalize to object ids.
  • Owners are also members. Promoting someone to owner who is already a member can trip duplicate logic if your code adds both a member and an owner reference separately.
Free download · 368-page PDF

Fixed it? Get 500 Microsoft Teams & DevOps AI prompts — free

500 battle-tested, copy-paste AI prompts engineered by a senior systems engineer — every one with fill-in placeholders and safety/back-out notes. Drop your email and it's yours.

  • 500 prompts: Linux · Kubernetes · Terraform · OpenStack · GitLab · Docker · Monitoring · Incident Response
  • Instant PDF download — yours free, forever
  • Plus one practical AI-workflow email a week (no spam)

Single opt-in · unsubscribe anytime · no spam.

Did this fix your issue?

Free download · 368-page PDF

Get 500 Battle-Tested DevOps AI Prompts — Free

500 battle-tested, copy-paste AI prompts engineered by a senior systems engineer — every one with fill-in placeholders and safety/back-out notes. Drop your email and it's yours.

  • 500 prompts: Linux · Kubernetes · Terraform · OpenStack · GitLab · Docker · Monitoring · Incident Response
  • Instant PDF download — yours free, forever
  • Plus one practical AI-workflow email a week (no spam)

Single opt-in · unsubscribe anytime · no spam.