Skip to content

[power-automate][Bug] flowagent: list_machine_groups selects a non-existent column; get_past_trigger_inputs sends Bearer to a SAS URL and mislabels the trigger #431

Description

Plugin 2.5.0 per .claude-plugin/plugin.json; the bundle's own User-Agent string says
power-automate-plugin/2.4.2.

All three reproduced against a live Dataverse-backed Sandbox environment (France Central), delegated
az auth as a licensed maker. Each was confirmed at source and by isolating the cause, not just by
observing a failure.

1. list_machine_groups cannot succeed: $select names a column that does not exist

dataverseMachineGroupsUrl (mcp.mjs:27799) builds:

const select = "flowmachinegroupid,name,description,grouptype,statecode";

There is no grouptype attribute on flowmachinegroup. Testing each column of that $select
individually against the same environment and identity:

$select= result
flowmachinegroupid 200
name 200
description 200
grouptype 400
statecode 200

Their exact URL, reconstructed from the source above:

GET {org}/api/data/v9.2/flowmachinegroups?$select=flowmachinegroupid,name,description,grouptype,statecode&$filter=statecode eq 0&$top=50
-> 400 {"error":{"code":"0x80060888","message":"Could not find a property named 'grouptype' on type 'Microsoft.Dynamics.CRM.flowmachinegroup'."}}

The table itself is fine - GET /flowmachinegroups?$top=5 returns 200 with a row in the same
environment, so this is not an empty-environment artifact.

Fix: entity metadata
(EntityDefinitions(LogicalName='flowmachinegroup')/Attributes) shows the intended attribute is
flowgrouptype (with flowgrouptypename for the label). No attribute named grouptype exists.
As far as I can tell the tool cannot succeed in any environment as written.

2. get_past_trigger_inputs sends Authorization to a SAS URL, so inputs never resolve

getPastTriggerInputs fetches the SAS-signed inputsLink.uri via ppapiRequest
(mcp.mjs:29242) -> requestWithToken (mcp.mjs:30949), which sets unconditionally:

const headers = { Authorization: `Bearer ${token}`, ... };

Isolated by issuing the same live inputsLink URL twice, differing only in that header:

GET <inputsLink.uri>                              -> 200, 114 bytes
GET <inputsLink.uri>  Authorization: Bearer <tok> -> 401
   {"error":{"code":"DirectApiRequestHasMoreThanOneAuthorization",
    "message":"The request has SAS authentication scheme, 'Bearer' authorization scheme or
               internal token scheme. Only one scheme should be used."}}

So the header is the cause, not an expired link or a transient. Every call therefore lands in the
catch and returns the placeholder:

{ "triggerInputs": { "_note": "inputsLink fetch failed; trigger inputs unavailable for this run" } }

This is the exact failure the plugin documents twice and then commits:

  • references/error-troubleshooting.md lists DirectApiRequestHasMoreThanOneAuthorization with the
    fix "Don't add Authorization header to SAS URLs."
  • The agent-facing prompt at mcp.mjs:43386 says: "If the action has inputsLink.uri, GET it
    (no auth header - SAS URL) to see the resolved inputs."

Knock-on effect: contentDigest is computed over whatever triggerInputs ends up being, so
every run with an unfetchable link produces the same digest. I saw c5155f9e returned for two
different runs on two different flows. Since the field exists to "dedupe identical inputs", it
currently reports unrelated runs as identical.

Fix: fetch content links with a bare client, no Authorization header.

3. get_past_trigger_inputs returns an arbitrary action as the trigger

mcp.mjs:29235:

const triggerAction = Array.isArray(actions) && actions.length > 0 ? actions[0] : null;

on the stated assumption (mcp.mjs:29215) that "the trigger is always the first action in actions[]".

For Request/Button-triggered flows the trigger is not in actions[] at all, so actions[0] is
always an ordinary action. Two flows, both with a single manual Button trigger:

flow definition triggers run actions[] order actions[0]
A manual Load_target, Post_message Load_target
B manual Compute_batches, Load_settings Compute_batches

Note flow B: the run-actions endpoint returned the actions in reverse definition order, so the
position is not even stable between flows.

Predicted from the source that flow A would report triggerName: "Load_target", then ran the tool:

{ "runId": "0858415493027741...CU16", "triggerName": "Load_target", "triggerInputs": { "_note": "..." } }

Confirmed. Since this primitive backs "Test with previous run data", it would replay the wrong
payload.

Fix: resolve the trigger by name from the flow definition's triggers collection rather than by
position in actions[].


Reproduction environment

  • power-automate@power-platform-skills v2.5.0 (bundle UA 2.4.2), Node 24
  • Power Platform Sandbox, France Central, Dataverse-backed
  • Delegated az auth, licensed maker, flows with kind: "Button" Request triggers

Possibly a separate issue: server/mcp.mjs does not start standalone under Node 24. The esbuild CJS
shim at mcp.mjs:9-14 tests typeof require, which is undefined in an ES module, so loading
jsonwebtoken -> jws -> safe-buffer throws Error: Dynamic require of "buffer" is not supported.
Setting globalThis.require = createRequire(import.meta.url) before importing works around it. I did
not check whether the plugin's own node -e bootstrap avoids this, so this one is lower confidence
than the three above.


Unrelated to the three above, but noticed while reproducing: #280 independently reports ListCallbackUrlOperationBlocked on Request/Button triggers, which I also hit calling listCallbackUrl directly. That one is already closed; mentioning it only because it corroborates the platform behaviour.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions