·3 min read·Rishi

Eliminating Null Reference Errors in Power Automate Flows

power-automatetutorial
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!