Child Flows in Power Automate: Reuse, Pass Data, and Avoid Duplication
In this series: Power Automate gotchas
Copying the same approval wrapper, validation routine, or notification logic into ten flows feels fast on day one. On day sixty, every bug fix becomes ten edits and ten chances to miss a branch. Child flows let you centralize that logic while still keeping the parent flow readable.
Child flows are solution-first components
Put the child flow in a solution. That is not optional for the Run a Child Flow action. The parent and child must live in a solution so Power Platform can manage dependencies, connection references, and ALM metadata. If your reusable logic is sitting in My flows with no solution boundary, promote it before you try to reuse it.
Design the child as a contract. A good child flow has a clear trigger, clear inputs, clear outputs, and one responsibility. Think of it like a private API inside your Power Platform solution. The parent should not need to know the internals, only what values to send and what response to expect.
| Reuse candidate | Good child flow | Better left inline |
|---|---|---|
| Validate incoming request shape | Yes | No |
| Send standardized notification | Yes | Sometimes |
| One-off field assignment | No | Yes |
| Complex Dataverse lookup routine | Yes | No |
| Parent-specific business branch | Usually no | Yes |
| Shared audit logging | Yes | No |
Inputs should be boring and explicit
Use the manual trigger inputs deliberately. A child flow typically starts with Manually trigger a flow and defines the inputs the parent must supply. Keep the input list small and typed. If you need a larger payload, pass one JSON string or object-shaped text and parse it inside the child.
Avoid ambient dependencies. Do not make the child flow secretly depend on a parent variable name, a specific trigger schema, or a hard-coded environment value. Pass what it needs. Use environment variables for configuration. Use connection references for connectors.
{
"requestId": "REQ-1042",
"accountId": "0f8fad5b-d9cb-469f-a165-70867728950e",
"requestedBy": "maker@example.com",
"priority": "High",
"notify": true
}
Validate at the boundary. The first actions in the child should normalize and validate inputs. Use Compose actions with expressions like coalesce for defaults, and terminate early with a controlled response when required data is missing. That makes the failure belong to the contract, not to a random connector action halfway down the flow.
Outputs make reuse worth the effort
Respond to the parent with a shaped result. Use Respond to a PowerApps or flow to return values from the child. Do not rely on the parent reading internal child actions. The parent should receive a result object it can branch on, log, or pass to another flow.
{
"success": true,
"status": "Validated",
"message": "Request is valid and notification was queued.",
"auditId": "AUD-77881"
}
Return business status, not only technical status. A child flow can complete successfully while the business outcome is rejected, skipped, or already processed. Include a status field that the parent can evaluate without parsing a human message.
Error handling should be part of the contract
Use scopes for try and catch behavior. Put the main work in a scope, then add a failure scope that runs after failure, timeout, or skipped states as needed. The child should return a consistent error shape when it can recover enough to respond. If the failure is unrecoverable, make sure the parent has its own run-after handling on the Run a Child Flow action.
{
"success": false,
"status": "FailedValidation",
"message": "Account id was missing or invalid.",
"diagnosticCode": "VALIDATION-ACCOUNT-ID"
}
Respect synchronous execution. The parent waits for the child flow response. That is exactly what you want for validation, calculation, enrichment, and small reusable operations. It is not what you want for long-running orchestration that may take hours.
Use child flows for reusable decisions and services, not as a hiding place for every complicated branch.
Limits shape the architecture
Plan for boundaries. Child flows are synchronous from the parent perspective. They are subject to normal flow limits, action limits, connector throttling, and timeout behavior. Avoid deep nesting. Do not create circular designs where parent and child flows can call each other indirectly.
Be careful with connection context. The child flow runs with its configured connections. That is usually good because it centralizes privileges, but it also means ownership and service account choices matter. Document the connection reference purpose in the solution, especially when the child writes to Dataverse or sends external notifications.
ALM is where child flows pay back
Version the contract like you mean it. If you add an optional input, parents can keep working. If you rename an output or change a status value, you have made a breaking change. In managed solutions, that can become a deployment issue rather than a quick edit.
Use names that survive export. Name the child flow by its service behavior, not the first parent that used it. Names like Validate Request Payload, Send Standard Approval Notification, and Write Integration Audit Entry age better than Helper Flow 3.
Test parent and child together before export. A child flow can run correctly on its own and still fail from the parent because an input name changed, a connection reference is missing, or the response shape drifted. Keep one small parent flow or test path that exercises the real contract before you ship the solution.
Child flows are not a cleanliness trophy. They are a way to make repeated automation logic testable, deployable, and fixable in one place. Use them where the contract is stable, keep the input and output shape boring, and your future solution upgrades will feel less like a scavenger hunt.
Keep reading
Filter Rows: The Lookup GUID Is _parentcustomerid_value
Filter rows is Dataverse OData. Lookups filter on _logicalname_value, not the name. Filter array runs after the download, and @equals does not belong in that box.
Get a Row by ID: Missing Fails the Run, Empty List Rows Does Not
Get a row by ID fails the run when the GUID is missing. List rows with zero matches succeeds. Look up the business key and branch on empty.
When an HTTP Request Is Received: The Callback URL Is a Secret
The HTTP trigger URL carries a SAS signature. Anyone with it can start the flow. Restrict who can call, always Respond, and never treat that URL as public.
Power Automate Do Until: The Loop That Succeeds After Giving Up
A Do until that hits count or timeout still succeeds. Put Get inside the loop, add a Delay, and test the condition after the loop exits.
Power Automate Trigger Conditions: The Run That Never Appears
A trigger condition that is false does not start a run and does not leave run history. How the expression differs from a Condition action, and how to see the skipped checks.
Power Platform September 2026 Update: The App-Builder Skill, Agent Plugins, and the Refreshed Model-Driven UI
What matters in Microsoft's September 2026 Power Platform feature update: the model app-builder skill goes GA, the canvas authoring agent plugin goes GA, generative pages embed in forms and reach connectors, model-driven header refresh is GA with display density in preview, and Power Automate gets server-side search.
Newsletter
New posts, straight to your inbox
One email when a new post goes up. Double opt-in, unsubscribe anytime. Not a daily digest.
Comments
- No comments yet. Be the first.