You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
[power-automate][Bug] #342 still open in 3.0.1 — activation reassigns the PPAPI flow id, so get_flow_context cannot find the Dataverse row; auto-merge blocks the only workaround #414
Follow-up to #342, closed as fixed in v3.0.1 (via #393). The finding-3 false-negative is not fixed, and it is still the gate on the finding-2 clientdata fix from #318. Two defects are reported together because the second one blocks the only workaround for the first.
Bug A — get_flow_context false-negative: the Dataverse lookup is keyed on the PPAPI flow id, which is reassigned when a flow is activated
New information versus #342: there is now a single-variable causal repro. The false-negative is not environment-specific, as #318 concluded — it is activation-dependent. Activating a solution flow causes the Flow RP (PPAPI) to assign it a new flow id while the Dataverse workflowid stays unchanged. From that point getFlowContext — which looks the row up in Dataverse by the PPAPI id — cannot find it, reports inSolution: false, and updateFlow silently falls back to the PPAPI definition PATCH, which cannot express a connection-reference binding.
fallback dataverseWorkflowByUniqueUrl(instanceUrl, flowId) → filters workflowidunique against the same PPAPI id → no match
properties.workflowEntityId (= the Dataverse workflowid) and properties.workflowUniqueId are both present in the very PPAPI getFlow response that getFlowContext already fetches, and workflowEntityId appears 0 times in the shipped server/mcp.mjs.
Static confirmation that 3.0.1 did not touch this: the getFlowContext function body is byte-identical between 2.3.1 (where #342 reproduces) and 3.0.1 — sha256 of the function region 7cc419a6850d37d9, length 3777 in both. In the currently open PR #412 (v3.0.2) the only change inside that function is a bundler variable rename (url → url2), so it is not fixed on the current trajectory either.
Secondary symptom: the response is internally contradictory. connectionReferenceLogicalNames is populated — read straight from the PPAPI payload — while inSolution is false. The tool simultaneously demonstrates the flow is solution-bound with connection references and reports it is not in a solution.
Bug B — autoMergeConnectionRefs aborts update_flow with a false "No connected connection found", and has no opt-out
Addressing a solution flow by its Dataverse workflowid instead of the reassigned PPAPI id does make get_flow_context resolve correctly (see step 7 below), which would be a usable workaround for Bug A. But update_flow then dies before reaching the write path:
No connected connection found for shared_sharepointonline.
Create one with: create-connection --env=<envId> --connector=shared_sharepointonline
…while list_connections in the same session and environment returns exactly one connection for that connector with status: "Connected".
Two problems combine:
B1. It runs unconditionally and cannot be disabled.updateFlow gates it on opts.autoResolveConnectionRefs !== false, but autoResolveConnectionRefs appears exactly once in the whole bundle — at that check — and no tool-layer parameter ever sets it. So auto-merge always runs for any update_flow carrying a definition, and it runs before the solution/Dataverse routing, so it can abort an update that would otherwise have succeeded via clientdata. (copy_flow's pre-existing autoResolveConnections is a different, separately-named option and does not gate this.)
B2. The "connected" predicate does not match what the internal lookup returns. Resolution filters with
but when the environment has a Dataverse instance, listConnections resolves via dataverseConnectionReferencesUrl(...) — i.e. it reads Dataverse connection reference rows, which carry no status/statuses field. Every row is filtered out and the connector is reported as having no connected connection. (B2 is inferred from reading the bundle; the directly observable fact is the contradiction with list_connections.)
Why auto-merge fired at all here:currentRefs comes from getFlow(envId, flowId), and for that id the call returns properties.connectionReferences as {}. With no current refs the connector counts as missing, so auto-merge attempts resolution — and throws.
A related concern with the same code path: when auto-merge does resolve, it writes source: "Embedded". For a solution flow whose binding is a connection reference, an injected Embedded binding is not the correct shape.
Not fixed in PR #412:autoMergeConnectionRefs is byte-identical there (sha256 of the function region b77969aae0ea8eb5 in both), including the filter line above.
Steps to Reproduce
Environment: one unmanaged solution containing cloud flows bound to connection references. All ids truncated; <envId> etc. redacted.
Create a solution-aware flow carrying a connection reference directly in Dataverse — POST /api/data/v9.2/workflows with category=5, type=1, primaryentity='none', clientdata, plus header MSCRM.SolutionUniqueName: <solution>. Leave it deactivated (statecode=0). It has one OpenApiConnection action on shared_sharepointonline bound to connection reference <pub>_SharePoint.
list_flows → the PPAPI nameequals the Dataverse workflowid (2258af0e…).
update_flow with a changed definition → succeeds cleanly. Verified by reading Dataverse clientdata back: the definition change landed and the connection-reference envelope is intact (runtimeSource: "invoker", nested connection.connectionReferenceLogicalName). This is the fix(power-automate): v2.3.1 — editFlow, solution flow round-trip, resolvers, datasets (#314) #318 fix working, because the gate happened to pass.
publish_flow → the flow activates (Dataverse statecode=1, statuscode=2, confirmed by direct read-back).
list_flows again → the PPAPI name has changed to dff4ba6f…. The Dataverse workflowid is still 2258af0e…. Nothing else was touched; activation was the only variable.
get_flow_context on the new PPAPI id dff4ba6f… — the id list_flows now returns, i.e. the one any agent will use — gives inSolution: false, workflowId: null, warning: "workflow-not-found", while get_flow_context on the old id 2258af0e… (= the Dataverse workflowid) still gives inSolution: true, warning: null. Same flow, two ids, opposite answers.
Bug A confirmed:update_flow on dff4ba6f… with a valid definition → 400:
InvalidOpenApiFlow / WorkflowRunActionInputsMissingProperty:
The 'inputs' of workflow run action 'Read_Web_Title' of type 'OpenApiConnection'
is not valid. Property 'host.connectionReferenceName' is missing.
No partial write — modifiedon and clientdata unchanged — so it fails safe.
Bug B confirmed: retry the same update_flow addressing the flow by its Dataverse workflowid2258af0e… (the path that made get_flow_context resolve in step 7) → aborts with No connected connection found for shared_sharepointonline. Again no write occurs.
Blast radius in one environment: of 10 solution flows, 9 return inSolution: false / workflow-not-found. The one flow that resolves correctly is the only one never activated. All nine return a non-empty connectionReferenceLogicalNames.
That 1-vs-9 split, plus step 6, is what we believe explains #318's "Finding 3 — Not reproduced … May be env-specific." A never-activated flow reproduces nothing; an activated one always reproduces.
Expected Behavior
Bug A.get_flow_context should resolve the Dataverse row for an activated solution flow, returning inSolution: true with the real workflowId, so updateFlow's Dataverse clientdata path (the #318 fix) is reachable and update_flow succeeds on connection-reference flows. Suggested fix — prefer the id the PPAPI response already carries, keeping the current value as fallback:
and correspondingly use properties.workflowUniqueId for the workflowidunique fallback lookup rather than the PPAPI flow id.
Bug B.update_flow should not abort on a connector for which a Connected connection demonstrably exists and is visible to list_connections in the same session. Auto-merge should be opt-out at the tool layer (surface autoResolveConnectionRefs on update_flow) so a caller supplying its own connectionReferences, or wanting a solution flow's existing bindings left strictly alone, can disable it. An empty properties.connectionReferences on the PPAPI record should not by itself be read as "this connector has no binding" for a solution-bound flow.
Actual Behavior
Bug A. For any activated solution flow, get_flow_context returns inSolution: false with warning: "workflow-not-found" and workflowId: null, even though the flow is in an unmanaged solution and the same response lists its connection references. updateFlow therefore takes the PPAPI fallback and fails with WorkflowRunActionInputsMissingProperty: Property 'host.connectionReferenceName' is missing.
Bug B. Routing around Bug A by passing the Dataverse workflowid makes get_flow_context correct but update_flow aborts inside auto-merge, claiming no connected connection exists for a connector that has exactly one in Connected state. There is no way to disable the behaviour from the tool layer.
Net effect: there is no working update_flow path for an activated solution flow bound to connection references. The #318 fix is correct but remains unreachable — exactly what #342 reported.
Relevant Logs / Screenshots
get_flow_context — same flow, both ids, immediately after activation:
// new PPAPI id (the one list_flows returns)
{ "flowId": "dff4ba6f…", "displayName": "ZZ-CopyUpdateProbe",
"workflowId": null, "workflowIdUnique": null, "inSolution": false,
"solutionId": null, "solutionUniqueName": null, "category": null,
"connectionReferenceLogicalNames": ["<pub>_SharePoint"],
"warning": "workflow-not-found" }
// old id, equal to the Dataverse workflowid
{ "flowId": "2258af0e…", "displayName": "ZZ-CopyUpdateProbe",
"workflowId": "2258af0e…", "workflowIdUnique": "249a611f…", "inSolution": true,
"category": 5, "connectionReferenceLogicalNames": ["<pub>_SharePoint"],
"warning": null }
update_flow on the new PPAPI id (Bug A):
Flow API 400 Bad Request: {"error":{"code":"XrmApiRequestFailed","message":
"Request to XRM API failed with error: 'Message: Flow client error returned with status code
\"BadRequest\" and details \"{\"error\":{\"code\":\"InvalidOpenApiFlow\",\"message\":
\"Fehler beim Speichern des Flows. Code: WorkflowRunActionInputsMissingProperty, Meldung:
\\\"The 'inputs' of workflow run action 'Read_Web_Title' of type 'OpenApiConnection' is not
valid. Property 'host.connectionReferenceName' is missing.\\\".\"}}\". Code: 0x80060467
update_flow addressed by the Dataverse workflowid (Bug B), then list_connections seconds later:
No connected connection found for shared_sharepointonline.
Create one with: create-connection --env=<envId> --connector=shared_sharepointonline
Also observed: get_flow on the pre-activation id returns properties.connectionReferences as {} (empty) while get_flow on the current PPAPI id returns the full map; both ids still resolve at PPAPI for displayName.
Verified as working in 3.0.1, for completeness:copy_flow (previously TypeError: ctx.getClient(...).copyFlow is not a function) now works and preserves the connection-reference envelope, dropping solution membership as documented; publish_flow activated an API-created solution flow successfully; and update_flow is clean on a solution flow that has never been activated (step 4).
Plugin
power-automate
Plugin Version
3.0.1
Skill / Command
N/A — FlowAgent MCP tools:
get_flow_context,update_flow,list_flows,publish_flow,list_connectionsBug Description
Follow-up to #342, closed as fixed in v3.0.1 (via #393). The finding-3 false-negative is not fixed, and it is still the gate on the finding-2
clientdatafix from #318. Two defects are reported together because the second one blocks the only workaround for the first.Bug A —
get_flow_contextfalse-negative: the Dataverse lookup is keyed on the PPAPI flow id, which is reassigned when a flow is activatedNew information versus #342: there is now a single-variable causal repro. The false-negative is not environment-specific, as #318 concluded — it is activation-dependent. Activating a solution flow causes the Flow RP (PPAPI) to assign it a new flow id while the Dataverse
workflowidstays unchanged. From that pointgetFlowContext— which looks the row up in Dataverse by the PPAPI id — cannot find it, reportsinSolution: false, andupdateFlowsilently falls back to the PPAPI definition PATCH, which cannot express a connection-reference binding.Root cause, unchanged from #342:
dataverseWorkflowUrl(instanceUrl, flowId)→workflows(<ppapiFlowId>)→ 404dataverseWorkflowByUniqueUrl(instanceUrl, flowId)→ filtersworkflowiduniqueagainst the same PPAPI id → no matchproperties.workflowEntityId(= the Dataverseworkflowid) andproperties.workflowUniqueIdare both present in the very PPAPIgetFlowresponse thatgetFlowContextalready fetches, andworkflowEntityIdappears 0 times in the shippedserver/mcp.mjs.Static confirmation that 3.0.1 did not touch this: the
getFlowContextfunction body is byte-identical between 2.3.1 (where #342 reproduces) and 3.0.1 — sha256 of the function region7cc419a6850d37d9, length 3777 in both. In the currently open PR #412 (v3.0.2) the only change inside that function is a bundler variable rename (url→url2), so it is not fixed on the current trajectory either.Secondary symptom: the response is internally contradictory.
connectionReferenceLogicalNamesis populated — read straight from the PPAPI payload — whileinSolutionisfalse. The tool simultaneously demonstrates the flow is solution-bound with connection references and reports it is not in a solution.Bug B —
autoMergeConnectionRefsabortsupdate_flowwith a false "No connected connection found", and has no opt-outAddressing a solution flow by its Dataverse
workflowidinstead of the reassigned PPAPI id does makeget_flow_contextresolve correctly (see step 7 below), which would be a usable workaround for Bug A. Butupdate_flowthen dies before reaching the write path:…while
list_connectionsin the same session and environment returns exactly one connection for that connector withstatus: "Connected".Two problems combine:
B1. It runs unconditionally and cannot be disabled.
updateFlowgates it onopts.autoResolveConnectionRefs !== false, butautoResolveConnectionRefsappears exactly once in the whole bundle — at that check — and no tool-layer parameter ever sets it. So auto-merge always runs for anyupdate_flowcarrying a definition, and it runs before the solution/Dataverse routing, so it can abort an update that would otherwise have succeeded viaclientdata. (copy_flow's pre-existingautoResolveConnectionsis a different, separately-named option and does not gate this.)B2. The "connected" predicate does not match what the internal lookup returns. Resolution filters with
but when the environment has a Dataverse instance,
listConnectionsresolves viadataverseConnectionReferencesUrl(...)— i.e. it reads Dataverse connection reference rows, which carry nostatus/statusesfield. Every row is filtered out and the connector is reported as having no connected connection. (B2 is inferred from reading the bundle; the directly observable fact is the contradiction withlist_connections.)Why auto-merge fired at all here:
currentRefscomes fromgetFlow(envId, flowId), and for that id the call returnsproperties.connectionReferencesas{}. With no current refs the connector counts as missing, so auto-merge attempts resolution — and throws.A related concern with the same code path: when auto-merge does resolve, it writes
source: "Embedded". For a solution flow whose binding is a connection reference, an injectedEmbeddedbinding is not the correct shape.Not fixed in PR #412:
autoMergeConnectionRefsis byte-identical there (sha256 of the function regionb77969aae0ea8eb5in both), including the filter line above.Steps to Reproduce
Environment: one unmanaged solution containing cloud flows bound to connection references. All ids truncated;
<envId>etc. redacted.Create a solution-aware flow carrying a connection reference directly in Dataverse —
POST /api/data/v9.2/workflowswithcategory=5,type=1,primaryentity='none',clientdata, plus headerMSCRM.SolutionUniqueName: <solution>. Leave it deactivated (statecode=0). It has oneOpenApiConnectionaction onshared_sharepointonlinebound to connection reference<pub>_SharePoint.list_flows→ the PPAPInameequals the Dataverseworkflowid(2258af0e…).get_flow_context→ correct:{ "workflowId": "2258af0e…", "inSolution": true, "category": 5, "warning": null }.update_flowwith a changed definition → succeeds cleanly. Verified by reading Dataverseclientdataback: the definition change landed and the connection-reference envelope is intact (runtimeSource: "invoker", nestedconnection.connectionReferenceLogicalName). This is the fix(power-automate): v2.3.1 — editFlow, solution flow round-trip, resolvers, datasets (#314) #318 fix working, because the gate happened to pass.publish_flow→ the flow activates (Dataversestatecode=1,statuscode=2, confirmed by direct read-back).list_flowsagain → the PPAPInamehas changed todff4ba6f…. The Dataverseworkflowidis still2258af0e…. Nothing else was touched; activation was the only variable.get_flow_contexton the new PPAPI iddff4ba6f…— the idlist_flowsnow returns, i.e. the one any agent will use — givesinSolution: false,workflowId: null,warning: "workflow-not-found", whileget_flow_contexton the old id2258af0e…(= the Dataverseworkflowid) still givesinSolution: true,warning: null. Same flow, two ids, opposite answers.Bug A confirmed:
update_flowondff4ba6f…with a valid definition → 400:No partial write —
modifiedonandclientdataunchanged — so it fails safe.Bug B confirmed: retry the same
update_flowaddressing the flow by its Dataverseworkflowid2258af0e…(the path that madeget_flow_contextresolve in step 7) → aborts withNo connected connection found for shared_sharepointonline. Again no write occurs.Immediately call
list_connections { connector: "shared_sharepointonline" }→ one connection,status: "Connected",statuses: [{ "status": "Connected" }], contradicting step 9.Blast radius in one environment: of 10 solution flows, 9 return
inSolution: false/workflow-not-found. The one flow that resolves correctly is the only one never activated. All nine return a non-emptyconnectionReferenceLogicalNames.That 1-vs-9 split, plus step 6, is what we believe explains #318's "Finding 3 — Not reproduced … May be env-specific." A never-activated flow reproduces nothing; an activated one always reproduces.
Expected Behavior
Bug A.
get_flow_contextshould resolve the Dataverse row for an activated solution flow, returninginSolution: truewith the realworkflowId, soupdateFlow's Dataverseclientdatapath (the #318 fix) is reachable andupdate_flowsucceeds on connection-reference flows. Suggested fix — prefer the id the PPAPI response already carries, keeping the current value as fallback:and correspondingly use
properties.workflowUniqueIdfor theworkflowiduniquefallback lookup rather than the PPAPI flow id.Bug B.
update_flowshould not abort on a connector for which aConnectedconnection demonstrably exists and is visible tolist_connectionsin the same session. Auto-merge should be opt-out at the tool layer (surfaceautoResolveConnectionRefsonupdate_flow) so a caller supplying its ownconnectionReferences, or wanting a solution flow's existing bindings left strictly alone, can disable it. An emptyproperties.connectionReferenceson the PPAPI record should not by itself be read as "this connector has no binding" for a solution-bound flow.Actual Behavior
Bug A. For any activated solution flow,
get_flow_contextreturnsinSolution: falsewithwarning: "workflow-not-found"andworkflowId: null, even though the flow is in an unmanaged solution and the same response lists its connection references.updateFlowtherefore takes the PPAPI fallback and fails withWorkflowRunActionInputsMissingProperty: Property 'host.connectionReferenceName' is missing.Bug B. Routing around Bug A by passing the Dataverse
workflowidmakesget_flow_contextcorrect butupdate_flowaborts inside auto-merge, claiming no connected connection exists for a connector that has exactly one inConnectedstate. There is no way to disable the behaviour from the tool layer.Net effect: there is no working
update_flowpath for an activated solution flow bound to connection references. The #318 fix is correct but remains unreachable — exactly what #342 reported.Relevant Logs / Screenshots
get_flow_context— same flow, both ids, immediately after activation:update_flowon the new PPAPI id (Bug A):update_flowaddressed by the Dataverseworkflowid(Bug B), thenlist_connectionsseconds later:[ { "name": "0996fada…", "connector": "/providers/Microsoft.PowerApps/apis/shared_sharepointonline", "displayName": "<connection name>", "status": "Connected", "statuses": [ { "status": "Connected" } ], "owner": "<user>", "accountName": "<user>@<tenant>", "allowSharing": false } ]Relevant shipped code (
server/mcp.mjs, 3.0.1):Also observed:
get_flowon the pre-activation id returnsproperties.connectionReferencesas{}(empty) whileget_flowon the current PPAPI id returns the full map; both ids still resolve at PPAPI fordisplayName.Verified as working in 3.0.1, for completeness:
copy_flow(previouslyTypeError: ctx.getClient(...).copyFlow is not a function) now works and preserves the connection-reference envelope, dropping solution membership as documented;publish_flowactivated an API-created solution flow successfully; andupdate_flowis clean on a solution flow that has never been activated (step 4).Environment
server/mcp.mjsblob9a305feb…, matchingmain)europe002)🤖 This issue was created using the
/report-issueskill.