Eliminating Null Reference Errors in Power Automate Flows
Your flow works in testing, then fails in production with: "The template language expression cannot be evaluated because property 'fieldname' doesn't exist." This is a null reference error, and it is the most common runtime failure in Power Automate.
Why It Happens
When a Dataverse, SharePoint, or API response does not include a field — because it is null, empty, or optional — any expression referencing that field throws an error. The field literally does not exist in the JSON payload.
The Defensive Expressions
coalesce() — Your First Line of Defense
coalesce() returns the first non-null value from a list:
@coalesce(triggerOutputs()?['body/company'], 'No Company')
If company is null, the expression returns 'No Company' instead of crashing.
The Question Mark Operator
The ? in property access paths is critical. Compare:
❌ triggerOutputs()['body']['company'] — crashes if body or company is null
✅ triggerOutputs()?['body']?['company'] — returns null safely
Always use ?['property'] instead of ['property'] or .property notation.
if() for Conditional Logic
@if(
empty(triggerOutputs()?['body/phone']),
'N/A',
triggerOutputs()?['body/phone']
)
Combining for Nested Objects
For deeply nested fields that might not exist at any level:
@coalesce(
triggerOutputs()?['body']?['primarycontactid']?['fullname'],
'Unknown Contact'
)
Common Scenarios and Fixes
Lookup Fields
Lookup fields in Dataverse are objects, not simple values. A null lookup means the entire object is missing:
❌ triggerOutputs()?['body/_ownerid_value']
✅ coalesce(triggerOutputs()?['body/_ownerid_value'], '')
Array Access
Accessing an item in an array that might be empty:
❌ first(body('List_rows'))
✅ if(empty(body('List_rows')?['value']), null, first(body('List_rows')?['value']))
Or more concisely:
@first(coalesce(body('List_rows')?['value'], json('[]')))
HTTP Response Bodies
API responses might have different shapes based on status:
@if(
equals(outputs('HTTP')?['statusCode'], 200),
body('HTTP')?['data']?['result'],
'API Error'
)
Defensive Flow Design Patterns
1. Validate Early
Add a condition at the top of your flow that checks all required fields exist before processing:
@and(
not(empty(triggerOutputs()?['body/name'])),
not(empty(triggerOutputs()?['body/email'])),
greater(length(coalesce(triggerOutputs()?['body/items'], json('[]'))), 0)
)
If validation fails, terminate with a clear error message.
2. Use Compose for Intermediate Values
Instead of repeating long null-safe expressions, normalize values early:
- Compose
CustomerName:@coalesce(triggerOutputs()?['body/fullname'], 'Unknown') - Compose
CustomerEmail:@coalesce(triggerOutputs()?['body/emailaddress1'], '')
Then reference outputs('CustomerName') throughout the flow — clean and safe.
3. Schema Validation on HTTP Triggers
For flows triggered by HTTP requests, define a JSON schema on the trigger. Power Automate validates incoming requests against the schema and rejects malformed payloads before your flow logic even runs.
Key Takeaway
Use ?[] for every property access. Wrap anything that could be null in coalesce(). Validate required fields early. These three habits eliminate 95% of null reference errors and turn fragile flows into production-ready ones.
Comments
No comments yet. Be the first!