[object Object]

A platform team inherits a Dynamics environment with 28 custom workflow activities written in 2018. Half of them no longer have a clear owner. The classic workflow engine that hosts them is on the deprecation path. Choosing whether to rebuild, retire, or wrap them is the highest-leverage decision for the next year of platform work.

The Legacy Context

Custom workflow activities were the extensibility path for classic Dataverse workflows. Many are still in production. New work uses Power Automate plus custom connectors instead. The classic workflow designer is read-only on creation in 2026 wave 1, which means the existing CWAs still run but no new classic workflows can be built.

Lifecycle status:
- Existing classic workflows: continue to run
- New classic workflows: blocked at creation
- CWA assemblies: still load and execute
- Migration window: 18 to 24 months expected

Plan migration on a 12-month horizon, not a 24-month one. The deprecation timelines compress as the platform team prepares for retirement.

Modern Alternative: Custom Connectors

For extending Power Automate with custom logic, build a custom connector backed by an Azure Function. Same outcome, easier to version and share across flows. The connector exposes a clean OpenAPI surface; the Function holds the code. Both are easier to test than a CWA.

module.exports = async function (context, req) {
  const input = req.body;
  const result = await complexCalculation(input);
  context.res = { status: 200, body: result };
};

Wrap this in an OpenAPI spec, register it as a custom connector, and any flow can call it like a built-in action.

When CWAs Still Fit

Legacy workflow compatibility. Specific sync-transaction needs that Power Automate plus connector cannot meet. Edge cases only. The genuine fit is when the operation must be inside the Dataverse transaction (rollback on parent failure) and the transaction must complete in under two seconds. Power Automate is async by design and cannot offer the same transactional guarantee.

Sync inside-transaction CWA candidates:
- Rollup calculations that must commit with the parent record
- Validation that must block the API call on failure
- Single-database operations that benefit from no network hop

Most other use cases have moved to plugins, flows, or Functions.

Testing

Same pattern as plug-ins — FakeXrmEasy and integration tests. But CWAs are a shrinking tech; invest in modern alternatives. The test pattern is well understood and the tooling still works; the cost is the time spent maintaining a skill the team will not use on new projects.

CWA test layers:
- Unit: FakeXrmEasy for organization service mocks
- Integration: deploy to a sandbox, run with real data
- Regression: rerun on every assembly update

Migration

Inventory CWAs. For each: is the flow it supports still relevant? If yes, rebuild in Power Automate. If no, retire. The inventory is the load-bearing step. Most teams discover that 30 to 50 percent of CWAs support workflows that nobody uses anymore.

<fetch>
  <entity name="pluginassembly">
    <attribute name="name" />
    <attribute name="modifiedon" />
    <link-entity name="plugintype" from="pluginassemblyid" to="pluginassemblyid">
      <attribute name="typename" />
      <filter>
        <condition attribute="workflowactivitygroupname" operator="not-null" />
      </filter>
    </link-entity>
  </entity>
</fetch>

This pulls every CWA in the environment with the assembly name and type. Cross-reference against the workflow definitions to find the orphans.

Migration Sequence

For each CWA you decide to keep: rebuild in Power Automate or as a custom connector, test in parallel with the original, swap consumers one at a time, retire the CWA when the last consumer is converted. Do not big-bang the migration; the parallel-run period is what catches the behavior differences.

Documentation Debt

Most CWAs have no documentation. The migration is the last chance to capture intent before the original developer is unreachable. Write a one-page summary per CWA that captures inputs, outputs, business purpose, and any non-obvious behavior. Store it in the same place as your other platform docs.

What to do this week

Run the inventory query, classify each CWA into Keep, Rebuild, or Retire, and pick one Rebuild candidate to convert as a proof point. Document the chosen one as you go and use that doc as the template for the rest.

[object Object]
Share