flowstudio-power-automate-debug
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChinesePower Automate Debugging with FlowStudio MCP
使用FlowStudio MCP调试Power Automate
A step-by-step diagnostic process for investigating failing Power Automate
cloud flows through the FlowStudio MCP server.
Prerequisite: A FlowStudio MCP server must be reachable with a valid JWT.
See the skill for connection setup.
Subscribe at https://mcp.flowstudio.app
flowstudio-power-automate-mcpSubscribe at https://mcp.flowstudio.app
通过FlowStudio MCP服务器调查故障Power Automate云流的分步诊断流程。
前提条件:必须能通过有效的JWT访问FlowStudio MCP服务器。连接设置请参考技能。
订阅地址:https://mcp.flowstudio.app
flowstudio-power-automate-mcp订阅地址:https://mcp.flowstudio.app
Source of Truth
权威来源
Always callfirst to confirm available tool names and their parameter schemas. Tool names and parameters may change between server versions. This skill covers response shapes, behavioral notes, and diagnostic patterns — thingstools/listcannot tell you. If this document disagrees withtools/listor a real API response, the API wins.tools/list
**请始终先调用**以确认可用工具名称及其参数 schema。工具名称和参数可能会随服务器版本变化。 本技能涵盖响应格式、行为说明和诊断模式——这些是tools/list无法提供的信息。如果本文档与tools/list或实际API响应存在冲突,以API为准。tools/list
Python Helper
Python辅助工具
python
import json, urllib.request
MCP_URL = "https://mcp.flowstudio.app/mcp"
MCP_TOKEN = "<YOUR_JWT_TOKEN>"
def mcp(tool, **kwargs):
payload = json.dumps({"jsonrpc": "2.0", "id": 1, "method": "tools/call",
"params": {"name": tool, "arguments": kwargs}}).encode()
req = urllib.request.Request(MCP_URL, data=payload,
headers={"x-api-key": MCP_TOKEN, "Content-Type": "application/json",
"User-Agent": "FlowStudio-MCP/1.0"})
try:
resp = urllib.request.urlopen(req, timeout=120)
except urllib.error.HTTPError as e:
body = e.read().decode("utf-8", errors="replace")
raise RuntimeError(f"MCP HTTP {e.code}: {body[:200]}") from e
raw = json.loads(resp.read())
if "error" in raw:
raise RuntimeError(f"MCP error: {json.dumps(raw['error'])}")
return json.loads(raw["result"]["content"][0]["text"])
ENV = "<environment-id>" # e.g. Default-xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxxpython
import json, urllib.request
MCP_URL = "https://mcp.flowstudio.app/mcp"
MCP_TOKEN = "<YOUR_JWT_TOKEN>"
def mcp(tool, **kwargs):
payload = json.dumps({"jsonrpc": "2.0", "id": 1, "method": "tools/call",
"params": {"name": tool, "arguments": kwargs}}).encode()
req = urllib.request.Request(MCP_URL, data=payload,
headers={"x-api-key": MCP_TOKEN, "Content-Type": "application/json",
"User-Agent": "FlowStudio-MCP/1.0"})
try:
resp = urllib.request.urlopen(req, timeout=120)
except urllib.error.HTTPError as e:
body = e.read().decode("utf-8", errors="replace")
raise RuntimeError(f"MCP HTTP {e.code}: {body[:200]}") from e
raw = json.loads(resp.read())
if "error" in raw:
raise RuntimeError(f"MCP error: {json.dumps(raw['error'])}")
return json.loads(raw["result"]["content"][0]["text"])
ENV = "<environment-id>" # 示例:Default-xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxxFlowStudio for Teams: Fast-Path Diagnosis (Skip Steps 2–4)
Teams版FlowStudio:快速诊断(跳过步骤2-4)
If you have a FlowStudio for Teams subscription,
returns per-run failure data including action names and remediation hints
in a single call — no need to walk through live API steps.
get_store_flow_errorspython
undefined如果你拥有Teams版FlowStudio订阅,接口可一次性返回每个运行实例的故障数据,包括操作名称和修复提示——无需逐步调用实时API。
get_store_flow_errorspython
undefinedQuick failure summary
快速故障汇总
summary = mcp("get_store_flow_summary", environmentName=ENV, flowName=FLOW_ID)
summary = mcp("get_store_flow_summary", environmentName=ENV, flowName=FLOW_ID)
{"totalRuns": 100, "failRuns": 10, "failRate": 0.1,
{"totalRuns": 100, "failRuns": 10, "failRate": 0.1,
"averageDurationSeconds": 29.4, "maxDurationSeconds": 158.9,
"averageDurationSeconds": 29.4, "maxDurationSeconds": 158.9,
"firstFailRunRemediation": "<hint or null>"}
"firstFailRunRemediation": "<提示内容或null>"}
print(f"Fail rate: {summary['failRate']:.0%} over {summary['totalRuns']} runs")
print(f"故障占比:{summary['failRate']:.0%}(共{summary['totalRuns']}次运行)")
Per-run error details (requires active monitoring to be configured)
单运行实例错误详情(需配置主动监控)
errors = mcp("get_store_flow_errors", environmentName=ENV, flowName=FLOW_ID)
if errors:
for r in errors[:3]:
print(r["startTime"], "|", r.get("failedActions"), "|", r.get("remediationHint"))
# If errors confirms the failing action → jump to Step 6 (apply fix)
else:
# Store doesn't have run-level detail for this flow — use live tools (Steps 2–5)
pass
For the full governance record (description, complexity, tier, connector list):
```python
record = mcp("get_store_flow", environmentName=ENV, flowName=FLOW_ID)errors = mcp("get_store_flow_errors", environmentName=ENV, flowName=FLOW_ID)
if errors:
for r in errors[:3]:
print(r["startTime"], "|", r.get("failedActions"), "|", r.get("remediationHint"))
# 如果errors确认了故障操作 → 跳至步骤6(应用修复)
else:
# 存储中没有此流的运行实例详情 → 使用实时工具(步骤2-5)
pass
如需完整治理记录(描述、复杂度、层级、连接器列表):
```python
record = mcp("get_store_flow", environmentName=ENV, flowName=FLOW_ID){"displayName": "My Flow", "state": "Started",
{"displayName": "My Flow", "state": "Started",
"runPeriodTotal": 100, "runPeriodFailRate": 0.1, "runPeriodFails": 10,
"runPeriodTotal": 100, "runPeriodFailRate": 0.1, "runPeriodFails": 10,
"runPeriodDurationAverage": 29410.8, ← milliseconds
"runPeriodDurationAverage": 29410.8, ← 毫秒
"runError": "{"code": "EACCES", ...}", ← JSON string, parse it
"runError": "{"code": "EACCES", ...}", ← JSON字符串,需解析
"description": "...", "tier": "Premium", "complexity": "{...}"}
"description": "...", "tier": "Premium", "complexity": "{...}"}
if record.get("runError"):
last_err = json.loads(record["runError"])
print("Last run error:", last_err)
---if record.get("runError"):
last_err = json.loads(record["runError"])
print("上次运行错误:", last_err)
---Step 1 — Locate the Flow
步骤1 — 定位目标流
python
result = mcp("list_live_flows", environmentName=ENV)python
result = mcp("list_live_flows", environmentName=ENV)Returns a wrapper object: {mode, flows, totalCount, error}
返回包装对象:{mode, flows, totalCount, error}
target = next(f for f in result["flows"] if "My Flow Name" in f["displayName"])
FLOW_ID = target["id"] # plain UUID — use directly as flowName
print(FLOW_ID)
---target = next(f for f in result["flows"] if "My Flow Name" in f["displayName"])
FLOW_ID = target["id"] # 纯UUID — 直接作为flowName使用
print(FLOW_ID)
---Step 2 — Find the Failing Run
步骤2 — 查找故障运行实例
python
runs = mcp("get_live_flow_runs", environmentName=ENV, flowName=FLOW_ID, top=5)python
runs = mcp("get_live_flow_runs", environmentName=ENV, flowName=FLOW_ID, top=5)Returns direct array (newest first):
返回直接数组(按时间倒序):
[{"name": "08584296068667933411438594643CU15",
[{"name": "08584296068667933411438594643CU15",
"status": "Failed",
"status": "Failed",
"startTime": "2026-02-25T06:13:38.6910688Z",
"startTime": "2026-02-25T06:13:38.6910688Z",
"endTime": "2026-02-25T06:15:24.1995008Z",
"endTime": "2026-02-25T06:15:24.1995008Z",
"triggerName": "manual",
"triggerName": "manual",
"error": {"code": "ActionFailed", "message": "An action failed..."}},
"error": {"code": "ActionFailed", "message": "An action failed..."}},
{"name": "...", "status": "Succeeded", "error": null, ...}]
{"name": "...", "status": "Succeeded", "error": null, ...}]
for r in runs:
print(r["name"], r["status"], r["startTime"])
RUN_ID = next(r["name"] for r in runs if r["status"] == "Failed")
---for r in runs:
print(r["name"], r["status"], r["startTime"])
RUN_ID = next(r["name"] for r in runs if r["status"] == "Failed")
---Step 3 — Get the Top-Level Error
步骤3 — 获取顶层错误信息
python
err = mcp("get_live_flow_run_error",
environmentName=ENV, flowName=FLOW_ID, runName=RUN_ID)python
err = mcp("get_live_flow_run_error",
environmentName=ENV, flowName=FLOW_ID, runName=RUN_ID)Returns:
返回:
{
{
"runName": "08584296068667933411438594643CU15",
"runName": "08584296068667933411438594643CU15",
"failedActions": [
"failedActions": [
{"actionName": "Apply_to_each_prepare_workers", "status": "Failed",
{"actionName": "Apply_to_each_prepare_workers", "status": "Failed",
"error": {"code": "ActionFailed", "message": "An action failed..."},
"error": {"code": "ActionFailed", "message": "An action failed..."},
"startTime": "...", "endTime": "..."},
"startTime": "...", "endTime": "..."},
{"actionName": "HTTP_find_AD_User_by_Name", "status": "Failed",
{"actionName": "HTTP_find_AD_User_by_Name", "status": "Failed",
"code": "NotSpecified", "startTime": "...", "endTime": "..."}
"code": "NotSpecified", "startTime": "...", "endTime": "..."}
],
],
"allActions": [
"allActions": [
{"actionName": "Apply_to_each", "status": "Skipped"},
{"actionName": "Apply_to_each", "status": "Skipped"},
{"actionName": "Compose_WeekEnd", "status": "Succeeded"},
{"actionName": "Compose_WeekEnd", "status": "Succeeded"},
...
...
]
]
}
}
failedActions is ordered outer-to-inner. The ROOT cause is the LAST entry:
failedActions按从外到内的顺序排列。根本原因是最后一个条目:
root = err["failedActions"][-1]
print(f"Root action: {root['actionName']} → code: {root.get('code')}")
root = err["failedActions"][-1]
print(f"根源操作:{root['actionName']} → 错误码:{root.get('code')}")
allActions shows every action's status — useful for spotting what was Skipped
allActions展示所有操作的状态 — 有助于发现被跳过的操作
See common-errors.md to decode the error code.
请参考common-errors.md解析错误码。
---
---Step 4 — Read the Flow Definition
步骤4 — 读取流定义
python
defn = mcp("get_live_flow", environmentName=ENV, flowName=FLOW_ID)
actions = defn["properties"]["definition"]["actions"]
print(list(actions.keys()))Find the failing action in the definition. Inspect its expression
to understand what data it expects.
inputspython
defn = mcp("get_live_flow", environmentName=ENV, flowName=FLOW_ID)
actions = defn["properties"]["definition"]["actions"]
print(list(actions.keys()))在定义中找到故障操作,检查其表达式以了解它期望的数据格式。
inputsStep 5 — Inspect Action Outputs (Walk Back from Failure)
步骤5 — 检查操作输出(从故障点回溯)
For each action leading up to the failure, inspect its runtime output:
python
for action_name in ["Compose_WeekEnd", "HTTP_Get_Data", "Parse_JSON"]:
result = mcp("get_live_flow_run_action_outputs",
environmentName=ENV,
flowName=FLOW_ID,
runName=RUN_ID,
actionName=action_name)
# Returns an array — single-element when actionName is provided
out = result[0] if result else {}
print(action_name, out.get("status"))
print(json.dumps(out.get("outputs", {}), indent=2)[:500])⚠️ Output payloads from array-processing actions can be very large. Always slice (e.g.) before printing.[:500]
对于故障发生前的每个操作,检查其运行时输出:
python
for action_name in ["Compose_WeekEnd", "HTTP_Get_Data", "Parse_JSON"]:
result = mcp("get_live_flow_run_action_outputs",
environmentName=ENV,
flowName=FLOW_ID,
runName=RUN_ID,
actionName=action_name)
# 返回数组 — 指定actionName时为单元素数组
out = result[0] if result else {}
print(action_name, out.get("status"))
print(json.dumps(out.get("outputs", {}), indent=2)[:500])⚠️ 数组处理操作的输出 payload 可能非常大。 打印前务必进行切片(例如)。[:500]
Step 6 — Pinpoint the Root Cause
步骤6 — 定位根本原因
Expression Errors (e.g. split
on null)
split表达式错误(如对null值执行split
)
splitIf the error mentions or a function name:
InvalidTemplate- Find the action in the definition
- Check what upstream action/expression it reads
- Inspect that upstream action's output for null / missing fields
python
undefined如果错误提及或函数名称:
InvalidTemplate- 在定义中找到对应的操作
- 检查它读取的上游操作/表达式
- 检查上游操作的输出是否存在null/缺失字段
python
undefinedExample: action uses split(item()?['Name'], ' ')
示例:操作使用split(item()?['Name'], ' ')
→ null Name in the source data
→ 源数据中Name字段为null
result = mcp("get_live_flow_run_action_outputs", ..., actionName="Compose_Names")
result = mcp("get_live_flow_run_action_outputs", ..., actionName="Compose_Names")
Returns a single-element array; index [0] to get the action object
返回单元素数组;通过索引[0]获取操作对象
if not result:
print("No outputs returned for Compose_Names")
names = []
else:
names = result[0].get("outputs", {}).get("body") or []
nulls = [x for x in names if x.get("Name") is None]
print(f"{len(nulls)} records with null Name")
undefinedif not result:
print("Compose_Names无输出返回")
names = []
else:
names = result[0].get("outputs", {}).get("body") or []
nulls = [x for x in names if x.get("Name") is None]
print(f"有{len(nulls)}条记录的Name字段为null")
undefinedWrong Field Path
字段路径错误
Expression returns null → is wrong.
Check the trigger output shape with:
triggerBody()?['fieldName']fieldNamepython
mcp("get_live_flow_run_action_outputs", ..., actionName="<trigger-action-name>")表达式返回null → 路径错误。
使用以下命令检查触发器输出格式:
triggerBody()?['fieldName']fieldNamepython
mcp("get_live_flow_run_action_outputs", ..., actionName="<trigger-action-name>")Connection / Auth Failures
连接/授权故障
Look for — the connection owner must match the
service account running the flow. Cannot fix via API; fix in PA designer.
ConnectionAuthorizationFailed如果出现错误 — 连接所有者必须与运行流的服务账户匹配。无法通过API修复;请在Power Automate设计器中处理。
ConnectionAuthorizationFailedStep 7 — Apply the Fix
步骤7 — 应用修复
For expression/data issues:
python
defn = mcp("get_live_flow", environmentName=ENV, flowName=FLOW_ID)
acts = defn["properties"]["definition"]["actions"]针对表达式/数据问题:
python
defn = mcp("get_live_flow", environmentName=ENV, flowName=FLOW_ID)
acts = defn["properties"]["definition"]["actions"]Example: fix split on potentially-null Name
示例:修复对可能为null的Name字段执行split的问题
acts["Compose_Names"]["inputs"] =
"@coalesce(item()?['Name'], 'Unknown')"
"@coalesce(item()?['Name'], 'Unknown')"
conn_refs = defn["properties"]["connectionReferences"]
result = mcp("update_live_flow",
environmentName=ENV,
flowName=FLOW_ID,
definition=defn["properties"]["definition"],
connectionReferences=conn_refs)
print(result.get("error")) # None = success
> ⚠️ `update_live_flow` always returns an `error` key.
> A value of `null` (Python `None`) means success.
---acts["Compose_Names"]["inputs"] =
"@coalesce(item()?['Name'], 'Unknown')"
"@coalesce(item()?['Name'], 'Unknown')"
conn_refs = defn["properties"]["connectionReferences"]
result = mcp("update_live_flow",
environmentName=ENV,
flowName=FLOW_ID,
definition=defn["properties"]["definition"],
connectionReferences=conn_refs)
print(result.get("error")) # None表示成功
> ⚠️ `update_live_flow`接口始终返回`error`键。
> 值为`null`(Python中为`None`)表示操作成功。
---Step 8 — Verify the Fix
步骤8 — 验证修复效果
python
undefinedpython
undefinedResubmit the failed run
重新提交故障运行实例
resubmit = mcp("resubmit_live_flow_run",
environmentName=ENV, flowName=FLOW_ID, runName=RUN_ID)
print(resubmit)
resubmit = mcp("resubmit_live_flow_run",
environmentName=ENV, flowName=FLOW_ID, runName=RUN_ID)
print(resubmit)
Wait ~30 s then check
等待约30秒后检查
import time; time.sleep(30)
new_runs = mcp("get_live_flow_runs", environmentName=ENV, flowName=FLOW_ID, top=3)
print(new_runs[0]["status"]) # Succeeded = done
undefinedimport time; time.sleep(30)
new_runs = mcp("get_live_flow_runs", environmentName=ENV, flowName=FLOW_ID, top=3)
print(new_runs[0]["status"]) # Succeeded表示修复完成
undefinedTesting HTTP-Triggered Flows
测试HTTP触发的流
For flows with a (HTTP) trigger, use instead
of to test with custom payloads:
Requesttrigger_live_flowresubmit_live_flow_runpython
undefined对于使用(HTTP)触发器的流,请使用而非,以便使用自定义payload进行测试:
Requesttrigger_live_flowresubmit_live_flow_runpython
undefinedFirst inspect what the trigger expects
首先检查触发器的预期格式
schema = mcp("get_live_flow_http_schema",
environmentName=ENV, flowName=FLOW_ID)
print("Expected body schema:", schema.get("triggerSchema"))
print("Response schemas:", schema.get("responseSchemas"))
schema = mcp("get_live_flow_http_schema",
environmentName=ENV, flowName=FLOW_ID)
print("预期请求体格式:", schema.get("triggerSchema"))
print("响应格式:", schema.get("responseSchemas"))
Trigger with a test payload
使用测试payload触发流
result = mcp("trigger_live_flow",
environmentName=ENV,
flowName=FLOW_ID,
body={"name": "Test User", "value": 42})
print(f"Status: {result['status']}, Body: {result.get('body')}")
> `trigger_live_flow` handles AAD-authenticated triggers automatically.
> Only works for flows with a `Request` (HTTP) trigger type.
---result = mcp("trigger_live_flow",
environmentName=ENV,
flowName=FLOW_ID,
body={"name": "Test User", "value": 42})
print(f"状态:{result['status']}, 响应体:{result.get('body')}")
> `trigger_live_flow`接口会自动处理AAD认证的触发器。
> 仅适用于使用`Request`(HTTP)触发器类型的流。
---Quick-Reference Diagnostic Decision Tree
快速参考诊断决策树
| Symptom | First Tool to Call | What to Look For |
|---|---|---|
| Flow shows as Failed | | |
| Expression crash | | null / wrong-type fields in output body |
| Flow never starts | | check |
| Action returns wrong data | | actual output body vs expected |
| Fix applied but still fails | | new run |
| 症状 | 首先调用的工具 | 检查要点 |
|---|---|---|
| 流显示为Failed | | |
| 表达式崩溃 | 对上游操作调用 | 输出体中的null/类型错误字段 |
| 流从未启动 | | 检查 |
| 操作返回错误数据 | | 实际输出体与预期的差异 |
| 已应用修复但仍故障 | 重新提交后调用 | 新运行实例的 |
Reference Files
参考文档
- common-errors.md — Error codes, likely causes, and fixes
- debug-workflow.md — Full decision tree for complex failures
- common-errors.md — 错误码、可能原因及修复方案
- debug-workflow.md — 复杂故障的完整决策树
Related Skills
相关技能
- — Core connection setup and operation reference
flowstudio-power-automate-mcp - — Build and deploy new flows
flowstudio-power-automate-build
- — 核心连接设置与操作参考
flowstudio-power-automate-mcp - — 构建与部署新流
flowstudio-power-automate-build