Skip to content

add-dataverse-api: Dataverse function calls fail for Edm.Guid and collection parameters (0x80060888) — codegen types Guid as string; toODataLiteral does not serialize collections #395

Description

@ranjith7022

Context

I was looking for the code-apps equivalent of the canvas Power Fx DataSourceInfo(dataSource, CreatePermission) (docs). The natural equivalent is the Dataverse functions RetrieveAadUserPrivileges and RetrieveAadUserSetOfPrivilegesByNames, added via npx power-apps add-dataverse-api. Calling the generated services failed — it traced back to a codegen bug in parameter serialization for OData function params.

Environment

  • @microsoft/power-apps 1.2.5
  • @microsoft/power-apps-cli 0.12.3

Repro

npx power-apps init -e <envId> -n "repro" -t CodeApp
npx power-apps push                      # register the app
npx power-apps add-dataverse-api --api-name RetrieveAadUserPrivileges
npx power-apps add-dataverse-api --api-name RetrieveAadUserSetOfPrivilegesByNames
import { getContext } from "@microsoft/power-apps/app";
const { user } = await getContext();

// Bug 1 (Guid):
await RetrieveAadUserPrivilegesService.RetrieveAadUserPrivileges(user.objectId);

// Bug 2 (collection):
await RetrieveAadUserSetOfPrivilegesByNamesService.RetrieveAadUserSetOfPrivilegesByNames(
  user.objectId,
  ["prvCreateAccount"],
);

Actual

  • RetrieveAadUserPrivileges400 0x80060888: "Expression of type 'Edm.String' cannot be converted to type 'Edm.Guid'."
  • RetrieveAadUserSetOfPrivilegesByNames400 0x80060888: "The parameter 'PrivilegeNames=prvCreateAccount' is not in scope."

Expected

Both calls succeed and return the user's privileges (RolePrivileges[]).

Root cause

The generated .power/schemas/appschemas/dataSourcesInfo.ts types:

  • DirectoryObjectId (CSDL Edm.Guid) → "type": "string"
  • PrivilegeNames (CSDL Collection(Edm.String)) → "type": "array"

The runtime toODataLiteral(value, type) (@microsoft/power-apps/dist/internal/data/core/data/executors/dataverseDataOperationExecutor.js:680) only special-cases type === 'string' (single-quoting); for everything else it returns String(value). For customapi GET functions, params are assembled into the OData function-call URL FunctionName(p=v,…) at :306-314 with no URL-encoding. Result:

  • Guid param (typed "string") → 'd2290e33-…' (quoted) → Dataverse rejects (string where Guid expected).
  • Collection param (typed "array") → String(["prvCreateAccount"]) = prvCreateAccount (bare token) → Dataverse rejects (not a collection literal).

Workarounds (app-side; both confirmed working)

  1. Guid — edit dataSourcesInfo.ts to set the param type to "guid"toODataLiteral returns the bare GUID → Dataverse accepts.
  2. Collection — pass encodeURIComponent(JSON.stringify(["prvCreateAccount"])) as the value → emits a valid encoded OData collection literal → Dataverse accepts.

After both, RetrieveAadUserSetOfPrivilegesByNames(objectId, ["prvCreateAccount"]) returns exactly the matching privilege:

{ "RolePrivileges": [ { "Depth": "Global", "PrivilegeName": "prvCreateAccount", "PrivilegeId": "d26fe964-230b-42dd-ad93-5cc879de411e" } ] }

Suggested fix

  • Codegen: map CSDL Edm.Guid → schema type: "guid" (not "string").
  • toODataLiteral: handle "guid" (emit bare value) and collection types (emit a JSON array literal, e.g. ["v1","v2"] with each element quoted).
  • URL encoding: URL-encode function-param values when building the function-call URL (or use OData alias syntax @p1 for collections).
  • Ensure add-dataverse-api regenerates dataSourcesInfo.ts so manual patches aren't required.

References

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions