Mastering Parse JSON in Power Automate: Schemas, Null Handling, and Arrays
Parse JSON looks like a convenience action, but in serious flows it is a contract boundary. It turns an unknown payload into typed dynamic content and makes later actions easier to read. It also fails loudly when the schema lies, which is exactly why you should learn to shape the schema instead of deleting the action.
Generate the schema, then edit it
Start from a real sample. The Generate from sample button is useful because it captures nesting, arrays, and primitive types quickly. But it assumes the sample is the whole truth. Real integrations send nulls, omit optional fields, and occasionally return an array with zero items.
Treat the generated schema as a draft. Review every required property, every nullable field, and every array item. If the schema came from a perfect happy-path response, it is almost certainly too strict for production.
Collect more than one sample. Ask for a normal payload, a payload with missing optional values, and a payload with an empty array. If the source is an HTTP action, save representative bodies from run history before finalizing the schema. One perfect example makes the designer happy; several realistic examples make the flow durable.
{
"type": "object",
"properties": {
"id": {
"type": "string"
},
"displayName": {
"type": "string"
},
"creditLimit": {
"type": "number"
}
},
"required": [
"id",
"displayName"
]
}
Nullable fields need type unions
Fix nulls at the schema level. The classic error says the action expected a string but got null. That is not a Power Automate mystery; it means the schema allowed only string while the payload sent null. If null is valid, use a type union.
{
"type": "object",
"properties": {
"email": {
"type": [
"string",
"null"
]
},
"phone": {
"type": [
"string",
"null"
]
},
"lastLoginOn": {
"type": [
"string",
"null"
]
}
}
}
Do not make everything nullable by habit. If a field is required for the process to work, keep it strict and fail early. Nullable schemas are for values that the upstream system legitimately may not know.
Required and optional are separate decisions
Type says what a value may be. Required says whether the property must exist. A field can be optional but, when present, must be a string. A field can be required and still allow null if the upstream contract always includes the property but sometimes has no value.
| Symptom | Likely cause | Fix |
|---|---|---|
Invalid type. Expected String but got Null | Property allows only string | Add null to the type array |
Required property is missing | Payload omitted a required field | Remove it from required or fix upstream |
| Dynamic content missing for array child | Schema item shape is incomplete | Define the array items object |
| Later action gets blank value | Property exists but is null | Use coalesce when reading it |
| Parse succeeds but loop fails | Array is sometimes empty | Guard with empty before indexing |
Arrays need an item contract
Define the shape inside items. For arrays, Power Automate needs to know what each element looks like. A vague array schema may parse, but it gives weak dynamic content and pushes risk into later expressions.
{
"type": "object",
"properties": {
"orders": {
"type": "array",
"items": {
"type": "object",
"properties": {
"orderId": {
"type": "string"
},
"amount": {
"type": "number"
},
"currency": {
"type": [
"string",
"null"
]
}
},
"required": [
"orderId",
"amount"
]
}
}
}
}
Loop over the parsed array, not the raw body. Once Parse JSON succeeds, use its typed output as the source for Apply to each. That keeps later references stable and makes schema changes visible in one place.
Decide what an empty array means. Sometimes it is a valid no-work response. Sometimes it means the upstream query was wrong. Add an explicit branch before the loop so the run history says skipped, no records, or failed validation. That is much better than a flow that quietly completes without doing the business work.
Nested access still needs safe expressions
Dynamic content is not a null shield. If a nested object can be missing, direct dynamic content may still fail in a later action. Use safe navigation in expressions when reading optional paths, and use coalesce for defaults.
body('Parse_JSON')?['customer']?['email']
coalesce(body('Parse_JSON')?['customer']?['email'], 'unknown@example.com')
first(body('Parse_JSON')?['orders'])?['orderId']
Guard array indexing. first is clean only when the array has at least one element. If an empty array is valid, check with empty before reading the first item or route to a no-data branch.
Sometimes json and body are enough
Use Parse JSON when the contract matters. If an HTTP action returns a payload used across many later steps, Parse JSON pays for itself with readable fields and early validation. If you only need one property from a simple object, body with safe navigation can be enough.
Use json for string payloads. Some triggers and connectors hand you JSON as text. The json expression converts it into an object so you can read properties without adding a Parse JSON action. That is useful for small transformations, but less useful when a shared schema would document the contract.
Log the raw payload when the contract is new. During early rollout, capture the response body in a secure logging destination or controlled audit table when parsing fails. Do not log secrets or personal data casually. The point is to see the real shape that broke the schema, fix the contract, and then reduce logging once the integration stabilizes.
Parse JSON is not just a designer helper. It is where you decide what your flow believes about incoming data. Generate the schema, edit it for nulls and optional fields, define array items properly, and your downstream actions will stop carrying the cost of a vague contract.
Keep reading
15 Power Automate Expressions Every Maker Should Memorize
Memorize these Power Automate expressions to build faster flows, handle nulls, shape arrays, format dates, reduce action count, and debug WDL.
Calling the Dataverse Web API from Power Automate with the HTTP Action
Learn when to call the Dataverse Web API from Power Automate for actions, functions, batch requests, impersonation, row association, and binds.
Child Flows in Power Automate: Reuse, Pass Data, and Avoid Duplication
Use child flows in Power Automate to centralize reusable logic, pass typed inputs and outputs, handle errors, reduce duplication, and improve ALM.
Newsletter
New posts, straight to your inbox
One email per post. No spam, no tracking pixels, unsubscribe anytime.
Comments
No comments yet. Be the first.