chore: publish from staged

This commit is contained in:
github-actions[bot]
2026-03-13 02:45:39 +00:00
parent b1f3346ef2
commit fcdf1a87ad
294 changed files with 47332 additions and 217 deletions

View File

@@ -0,0 +1,188 @@
# FlowStudio MCP — Common Power Automate Errors
Reference for error codes, likely causes, and recommended fixes when debugging
Power Automate flows via the FlowStudio MCP server.
---
## Expression / Template Errors
### `InvalidTemplate` — Function Applied to Null
**Full message pattern**: `"Unable to process template language expressions... function 'split' expects its first argument 'text' to be of type string"`
**Root cause**: An expression like `@split(item()?['Name'], ' ')` received a null value.
**Diagnosis**:
1. Note the action name in the error message
2. Call `get_live_flow_run_action_outputs` on the action that produces the array
3. Find items where `Name` (or the referenced field) is `null`
**Fixes**:
```
Before: @split(item()?['Name'], ' ')
After: @split(coalesce(item()?['Name'], ''), ' ')
Or guard the whole foreach body with a condition:
expression: "@not(empty(item()?['Name']))"
```
---
### `InvalidTemplate` — Wrong Expression Path
**Full message pattern**: `"Unable to process template language expressions... 'triggerBody()?['FieldName']' is of type 'Null'"`
**Root cause**: The field name in the expression doesn't match the actual payload schema.
**Diagnosis**:
```python
# Check trigger output shape
mcp("get_live_flow_run_action_outputs",
environmentName=ENV, flowName=FLOW_ID, runName=RUN_ID,
actionName="<trigger-name>")
# Compare actual keys vs expression
```
**Fix**: Update expression to use the correct key name. Common mismatches:
- `triggerBody()?['body']` vs `triggerBody()?['Body']` (case-sensitive)
- `triggerBody()?['Subject']` vs `triggerOutputs()?['body/Subject']`
---
### `InvalidTemplate` — Type Mismatch
**Full message pattern**: `"... expected type 'Array' but got type 'Object'"`
**Root cause**: Passing an object where the expression expects an array (e.g. a single item HTTP response vs a list response).
**Fix**:
```
Before: @outputs('HTTP')?['body']
After: @outputs('HTTP')?['body/value'] ← for OData list responses
@createArray(outputs('HTTP')?['body']) ← wrap single object in array
```
---
## Connection / Auth Errors
### `ConnectionAuthorizationFailed`
**Full message**: `"The API connection ... is not authorized."`
**Root cause**: The connection referenced in the flow is owned by a different
user/service account than the one whose JWT is being used.
**Diagnosis**: Check `properties.connectionReferences` — the `connectionName` GUID
identifies the owner. Cannot be fixed via API.
**Fix options**:
1. Open flow in Power Automate designer → re-authenticate the connection
2. Use a connection owned by the service account whose token you hold
3. Share the connection with the service account in PA admin
---
### `InvalidConnectionCredentials`
**Root cause**: The underlying OAuth token for the connection has expired or
the user's credentials changed.
**Fix**: Owner must sign in to Power Automate and refresh the connection.
---
## HTTP Action Errors
### `ActionFailed` — HTTP 4xx/5xx
**Full message pattern**: `"An HTTP request to... failed with status code '400'"`
**Diagnosis**:
```python
actions_out = mcp("get_live_flow_run_action_outputs", ..., actionName="HTTP_My_Call")
item = actions_out[0] # first entry in the returned array
print(item["outputs"]["statusCode"]) # 400, 401, 403, 500...
print(item["outputs"]["body"]) # error details from target API
```
**Common causes**:
- 401 — missing or expired auth header
- 403 — permission denied on target resource
- 404 — wrong URL / resource deleted
- 400 — malformed JSON body (check expression that builds the body)
---
### `ActionFailed` — HTTP Timeout
**Root cause**: Target endpoint did not respond within the connector's timeout
(default 90 s for HTTP action).
**Fix**: Add retry policy to the HTTP action, or split the payload into smaller
batches to reduce per-request processing time.
---
## Control Flow Errors
### `ActionSkipped` Instead of Running
**Root cause**: The `runAfter` condition wasn't met. E.g. an action set to
`runAfter: { "Prev": ["Succeeded"] }` won't run if `Prev` failed or was skipped.
**Diagnosis**: Check the preceding action's status. Deliberately skipped
(e.g. inside a false branch) is intentional — unexpected skip is a logic gap.
**Fix**: Add `"Failed"` or `"Skipped"` to the `runAfter` status array if the
action should run on those outcomes too.
---
### Foreach Runs in Wrong Order / Race Condition
**Root cause**: `Foreach` without `operationOptions: "Sequential"` runs
iterations in parallel, causing write conflicts or undefined ordering.
**Fix**: Add `"operationOptions": "Sequential"` to the Foreach action.
---
## Update / Deploy Errors
### `update_live_flow` Returns No-Op
**Symptom**: `result["updated"]` is empty list or `result["created"]` is empty.
**Likely cause**: Passing wrong parameter name. The required key is `definition`
(object), not `flowDefinition` or `body`.
---
### `update_live_flow` — `"Supply connectionReferences"`
**Root cause**: The definition contains `OpenApiConnection` or
`OpenApiConnectionWebhook` actions but `connectionReferences` was not passed.
**Fix**: Fetch the existing connection references with `get_live_flow` and pass
them as the `connectionReferences` argument.
---
## Data Logic Errors
### `union()` Overriding Correct Records with Nulls
**Symptom**: After merging two arrays, some records have null fields that existed
in one of the source arrays.
**Root cause**: `union(old_data, new_data)``union()` first-wins, so old_data
values override new_data for matching records.
**Fix**: Swap argument order: `union(new_data, old_data)`
```
Before: @sort(union(outputs('Old_Array'), body('New_Array')), 'Date')
After: @sort(union(body('New_Array'), outputs('Old_Array')), 'Date')
```

View File

@@ -0,0 +1,157 @@
# FlowStudio MCP — Debug Workflow
End-to-end decision tree for diagnosing Power Automate flow failures.
---
## Top-Level Decision Tree
```
Flow is failing
├── Flow never starts / no runs appear
│ └── ► Check flow State: get_live_flow → properties.state
│ ├── "Stopped" → flow is disabled; enable in PA designer
│ └── "Started" + no runs → trigger condition not met (check trigger config)
├── Flow run shows "Failed"
│ ├── Step A: get_live_flow_run_error → read error.code + error.message
│ │
│ ├── error.code = "InvalidTemplate"
│ │ └── ► Expression error (null value, wrong type, bad path)
│ │ └── See: Expression Error Workflow below
│ │
│ ├── error.code = "ConnectionAuthorizationFailed"
│ │ └── ► Connection owned by different user; fix in PA designer
│ │
│ ├── error.code = "ActionFailed" + message mentions HTTP
│ │ └── ► See: HTTP Action Workflow below
│ │
│ └── Unknown / generic error
│ └── ► Walk actions backwards (Step B below)
└── Flow Succeeds but output is wrong
└── ► Inspect intermediate actions with get_live_flow_run_action_outputs
└── See: Data Quality Workflow below
```
---
## Expression Error Workflow
```
InvalidTemplate error
├── 1. Read error.message — identifies the action name and function
├── 2. Get flow definition: get_live_flow
│ └── Find that action in definition["actions"][action_name]["inputs"]
│ └── Identify what upstream value the expression reads
├── 3. get_live_flow_run_action_outputs for the action BEFORE the failing one
│ └── Look for null / wrong type in that action's output
│ ├── Null string field → wrap with coalesce(): @coalesce(field, '')
│ ├── Null object → add empty check condition before the action
│ └── Wrong field name → correct the key (case-sensitive)
└── 4. Apply fix with update_live_flow, then resubmit
```
---
## HTTP Action Workflow
```
ActionFailed on HTTP action
├── 1. get_live_flow_run_action_outputs on the HTTP action
│ └── Read: outputs.statusCode, outputs.body
├── statusCode = 401
│ └── ► Auth header missing or expired OAuth token
│ Check: action inputs.authentication block
├── statusCode = 403
│ └── ► Insufficient permission on target resource
│ Check: service principal / user has access
├── statusCode = 400
│ └── ► Malformed request body
│ Check: action inputs.body expression; parse errors often in nested JSON
├── statusCode = 404
│ └── ► Wrong URL or resource deleted/renamed
│ Check: action inputs.uri expression
└── statusCode = 500 / timeout
└── ► Target system error; retry policy may help
Add: "retryPolicy": {"type": "Fixed", "count": 3, "interval": "PT10S"}
```
---
## Data Quality Workflow
```
Flow succeeds but output data is wrong
├── 1. Identify the first "wrong" output — which action produces it?
├── 2. get_live_flow_run_action_outputs on that action
│ └── Compare actual output body vs expected
├── Source array has nulls / unexpected values
│ ├── Check the trigger data — get_live_flow_run_action_outputs on trigger
│ └── Trace forward action by action until the value corrupts
├── Merge/union has wrong values
│ └── Check union argument order:
│ union(NEW, old) = new wins ✓
│ union(OLD, new) = old wins ← common bug
├── Foreach output missing items
│ ├── Check foreach condition — filter may be too strict
│ └── Check if parallel foreach caused race condition (add Sequential)
└── Date/time values wrong timezone
└── Use convertTimeZone() — utcNow() is always UTC
```
---
## Walk-Back Analysis (Unknown Failure)
When the error message doesn't clearly name a root cause:
```python
# 1. Get all action names from definition
defn = mcp("get_live_flow", environmentName=ENV, flowName=FLOW_ID)
actions = list(defn["properties"]["definition"]["actions"].keys())
# 2. Check status of each action in the failed run
for action in actions:
actions_out = mcp("get_live_flow_run_action_outputs",
environmentName=ENV, flowName=FLOW_ID, runName=RUN_ID,
actionName=action)
# Returns an array of action objects
item = actions_out[0] if actions_out else {}
status = item.get("status", "unknown")
print(f"{action}: {status}")
# 3. Find the boundary between Succeeded and Failed/Skipped
# The first Failed action is likely the root cause (unless skipped by design)
```
Actions inside Foreach / Condition branches may appear nested —
check the parent action first to confirm the branch ran at all.
---
## Post-Fix Verification Checklist
1. `update_live_flow` returns `error: null` — definition accepted
2. `resubmit_live_flow_run` confirms new run started
3. Wait for run completion (poll `get_live_flow_runs` every 15 s)
4. Confirm new run `status = "Succeeded"`
5. If flow has downstream consumers (child flows, emails, SharePoint writes),
spot-check those too