Microsoft Teams Bot Framework · error code

Teams error 400 Bad Argument: Bad Argument - invalid request payload

Permanent - do not retryHTTP 400Payload & request errors

Last verified against Microsoft Learn - Status codes from bot conversational APIs

What Teams returns
*scenario specific

What error 400 Bad Argument means

The Connector understood who you are but not what you sent. Microsoft's status table documents 400 as code Bad Argument with a scenario-specific message and the developer action "Reevaluate request payload for errors. Check returned error message for details." The retry column says No: the same payload will fail the same way forever, so retrying a 400 only burns your rate-limit budget.

In Teams practice the message body is where the diagnosis lives: a malformed conversation ID, an activity missing its required type, a card attachment whose contentType does not match its content, an invalid mention entity whose mentioned.id is not actually in the conversation, or JSON that serializes a null into a required field. Because the message text varies by scenario, log the full ErrorResponse body and the X-Correlating-OperationId header rather than just the status code.

What it looks like

{
  "error": {
    "code": "Bad Argument",
    "message": "Invalid ChannelData property..."
  }
}

Why it happens

  • A required activity field (type, conversation.id, recipient) is missing or null after serialization.
  • A card attachment's contentType does not match the payload (for example adaptive card JSON declared as hero card).
  • A mention entity references a user ID that is not a member of the conversation.
  • The conversation ID was truncated or URL-decoded incorrectly before being placed in the request path.

How to fix Teams error 400 Bad Argument

  1. 1Capture the response body - the scenario-specific message names the offending field.
  2. 2Serialize the failing activity to JSON in a debug log and validate it by eye against the Activity schema in the Connector API reference.
  3. 3Reproduce with a minimal activity (type + text only) to separate envelope problems from attachment problems, then add parts back until it breaks.
  4. 4Fix the payload at its source; do not add retry logic - the documented retry guidance for 400 is No.

How to stop it recurring

Build activities through the SDK's typed factories instead of raw dictionaries so required fields cannot be omitted silently. Validate card JSON in CI. Keep one integration test per card template you ship, run against a test tenant, so schema drift surfaces before release - the same discipline that keeps 413 payload-size failures out of production.

Official reference: Microsoft Learn - Status codes from bot conversational APIs. See all Teams error codes or the Teams limits and quotas.

Related codes

Error 400 Bad Argument - quick answers

What does Teams error 400 Bad Argument mean?

The Connector understood who you are but not what you sent. Microsoft's status table documents 400 as code Bad Argument with a scenario-specific message and the developer action "Reevaluate request payload for errors. Check returned error message for details." The retry column says No : the same payload will fail the same way forever, so retrying a 400 only burns your rate-limit budget .

How do I fix Teams error 400 Bad Argument?

1. Capture the response body - the scenario-specific message names the offending field. 2. Serialize the failing activity to JSON in a debug log and validate it by eye against the Activity schema in the Connector API reference. 3. Reproduce with a minimal activity (type + text only) to separate envelope problems from attachment problems, then add parts back until it breaks. 4. Fix the payload at its source; do not add retry logic - the documented retry guidance for 400 is No.

Should I retry after error 400 Bad Argument?

No. Retrying the same request produces the same error; the condition has to be fixed first. Treat it as a permanent failure for that message and surface it, rather than looping.

Stop debugging Teams by hand

Connect the channel through Conferbot: tokens, webhooks and retries are handled, failures show as readable status.