01What is error 100?
Error 100 (Invalid Parameter) is the Graph API's generic validation error, returned with "code": 100 and a message prefixed (#100) when a request can't be processed as written. On the WhatsApp Cloud API it covers everything from a missing messaging_product and an unknown key in the JSON body to a value that is too long, of the wrong type, or an ID the endpoint can't use. Meta's own description is short: the request included one or more unsupported or misspelled parameters.
The error is synchronous. The API answers the POST with HTTP 400 and an error object instead of a WAMID, so no message exists, no status webhook will follow and nothing is charged. The fields that matter are message (often naming the parameter, as in (#100) The parameter messaging_product is required.), type (usually OAuthException), error_subcode where present, error_data.details with WhatsApp-specific detail, and the fbtrace_id that Meta support uses to find the call.
Two variants cover most cases. Without a subcode, the body or query is malformed: a typo such as paramaters, a field at the wrong nesting level, a string where an object is expected, or a value outside its allowed length. With subcode 33 (type GraphMethodException, message Unsupported post request. Object with ID '…' does not exist, cannot be loaded due to missing permissions, or does not support this operation) the problem is the object in the URL: a WABA ID used where a phone number ID belongs, a number from another business, or a token whose system user was never assigned that asset.
Among the API error codes a WhatsApp integration meets, error 100 is the Graph-level catch-all, which separates it from WhatsApp's own parameter codes (131008 for a required parameter that is missing, 131009 for a value that isn't valid) and from template errors in the 132xxx range such as error 132000 (Parameter Count Mismatch), where the request is well formed but doesn't fit the approved template's placeholders.
Key takeaways
- Error 100 means the Graph API rejected the request itself: a parameter is missing, misspelled, unsupported, the wrong type or the wrong length.
- It comes back synchronously with HTTP 400, so no message was created, no webhook will follow and nothing is billed.
error.messageanderror_data.detailsusually name the offending field; read them before changing any code.- Subcode 33 (object does not exist or can't be loaded) almost always means a wrong ID or a token without access to that asset.
- Treat it as non-retryable: the identical request will fail again until the payload or the ID is fixed.
02Error 100 in code
{"error": {"message": "(#100) The parameter messaging_product is required.","type": "OAuthException","code": 100,"fbtrace_id": "AbCdEf1234567890xyz"}}
03 · How it works, step by step
How does error 100 work?
- Step 1
Log the full error object
Capture
code,error_subcode,message,error_data.detailsandfbtrace_idwith your own request ID. HTTP 400 alone doesn't distinguish error 100 from a dozen other codes. - Step 2
Read the named parameter
The message usually names the field (
messaging_product,template,components,to). Compare it with the messages endpoint reference for spelling, nesting level and type. - Step 3
Check the subcode for ID problems
Subcode 33 points at the object in the URL. Confirm you used the phone number ID (not the display number or the WABA ID) and that the token's system user is assigned that WABA.
- Step 4
Reproduce with a minimal payload
Strip the request to the smallest valid body, such as the
hello_worldtemplate, and add fields back one at a time. Replaying it with cURL takes your SDK's serialiser out of the picture. - Step 5
Validate before you send
Add schema validation in code so malformed payloads fail in your own logs, not at Meta. The API often reports only the first problem it finds, so validate the whole payload at once.
04 · Common mistakes, and the fix
Common mistakes with error 100
Retrying it automatically
A generic retry wrapper resends the same broken payload, burns rate limit and delays the alert. Mark error 100 as non-retryable and surface it to a developer.
Putting the wrong ID in the path
The display phone number, the WABA ID and the app ID all look like long numbers. Messages are sent to
/{PHONE_NUMBER_ID}/messages; anything else returns subcode 33.Logging only the HTTP status
HTTP status codes are coarse: “400 Bad Request” is shared by error 100, template errors and many WhatsApp codes. Without
code,messageanddetailsin the log, every incident starts from zero.Regenerating tokens for a typo
Subcode 33 mentions missing permissions, but an expired token is error 190 (Access Token Invalid). Fix asset assignment or the payload; a fresh token won't cure a misspelled key.
05Error 100: key facts and limits
- Code
- 100, message prefixed (#100)
- HTTP status
- 400 Bad Request
- Common subcode
- 33: object missing, inaccessible or unsupported
- When
- Synchronously, on the API call
- Billing
- Nothing sent, nothing charged
- Retry?
- No: fix the request first
- WhatsApp-specific cousins
- 131008 missing parameter · 131009 invalid value
06Example: The template that worked in staging, Ahmedabad
An Ahmedabad pharmacy chain moves its refill reminders from a staging WABA to production, and every send fails with Unsupported post request. Object with ID '1093…' does not exist and subcode 33. The payload is fine: the deploy config still points at the staging phone number ID, which the production system user can't see. Swapping in the production phone_number_id fixes it. A week later a second error 100, this time naming template['components'][0] in its message, turns out to be parameters misspelled during a refactor, found in minutes because the full message was logged.
07Why does error 100 matter?
Error 100 is the most common error in an integration's first week and again after every refactor, because every typo, schema drift and copy-paste of the wrong ID produces it. It is also cheap to fix when read properly: the message nearly always names the culprit. Teams that log the whole error object resolve it in minutes; teams that log only “request failed, 400” end up diffing payloads by hand.
08 · Tips from the bench
Best practices for error 100
- Keep a JSON Schema or a typed builder for every message type you send.
- Diff the failing payload against a known-good one before reading the docs.
- Store the phone number ID and WABA ID per environment and log which one each request used.
- When you see subcode 33, use the access token debugger to confirm which WABAs the token can reach.