Power Platform

The three things that break every Power Platform migration

Apps outside solutions, flows without connection references and buttons opening hardcoded URLs — the three findings that derail a Power Platform migration, and how to find them first.

LogiSam · 12 October 2026 · 9 min read
Power Insights banner: what breaks a Power Platform migration — apps outside solutions, missing connection references and hardcoded URLs

A Power Platform migration is almost always scoped from a list of apps. Somebody exports it from the admin centre, or writes it from memory, and that list becomes the plan.

It is never what actually moves.

Three findings come up on nearly every estate we are asked to migrate — tenant to tenant after an acquisition, default environment into something governed, or simply putting a real ALM path under apps that were built straight into production. None of them are exotic. All three are invisible until somebody opens the app on the far side, which is usually the week after go-live and usually in front of the customer.

Problem one: the apps and flows are not in a solution

Most of what a maker builds does not start life in a solution. You open the maker portal, you build the thing, and it lives in the environment directly — very often the default environment, which has no solution discipline by design and is where a surprising share of the estate ends up.

That is fine right up to the day it has to move. A solution is the unit of transport: it is what exports, what imports, and what carries environment-specific bindings across. An app outside one has no package to travel in. Microsoft's own ALM guidance on solutions is built on that assumption throughout.

You can export an individual canvas app as a .msapp, and people do. What that file does not bring with it is the flows the app calls, the connection references, the environment variables, or the dependency metadata the target needs in order to rebind anything. You get the screens. You do not get the application.

So the first real task is rarely "move the apps". It is "work out what has to be packaged together, then build the solutions" — and that has to be settled before anything is exported, because objects that must travel together need to be in the same package.

There is a second-order version of this that catches people even when they have done the work: an app pulled out of a solution its siblings are still in arrives in the target with references that rebind to nothing. Solution membership is itself a dependency, and it is not visible from a list of app names.

Problem two: connections instead of connection references

A connection reference is the indirection between a flow and the credential it runs as. The flow points at the reference, the reference points at the connection, and at import time the reference is the thing that gets rebound to a credential in the target.

Flows that predate connection references — and flows built outside a solution since — bind straight to a connection instead. There is no indirection to rebind. Two things follow, and the second is worse than the first.

First, every one of those flows has to be opened by hand in the target and re-pointed. On an estate of a few hundred flows that is not a task, it is a project, and it lands in the cutover weekend.

Second, and more quietly: a connection is an identity. A flow bound directly to a connection runs as whoever owns that connection — and after an import, that is frequently whoever did the import. Nothing warns you. The flow works. It is simply now running every night as the consultant who migrated it, against a personal account, until that person's access is removed and a production process stops on a Tuesday for reasons nobody can trace back.

Converting flows to connection references is the right fix, and the work is manageable once you know which flows need it. Finding out is the expensive part, because the answer lives inside each flow definition rather than in any list you can pull off an admin screen.

Problem three: buttons that open a hardcoded URL

This is the quietest of the three, and the one that bites after sign-off.

Somewhere in the app there is a button. It opens a SharePoint document library, or a Power BI report, and it does it with a literal address:

Launch("https://contoso.sharepoint.com/sites/Operations/Shared%20Documents")

Or a Patch() against a site referenced by its full URL. Or an embedded Power BI tile pointing at a workspace in the tenant you are leaving.

Every one of those keeps working after the migration. That is the trap. The source tenant usually still exists for a period — during an acquisition, for months — so the URL resolves, the page loads, the report renders, and the user has no reason to report anything. The app is quietly operating against the old tenant. People save documents there. Reports get read there. By the time anyone notices, there is a fortnight of real work sitting on the wrong side of the migration.

And none of it appears in an admin API. The admin APIs describe what an app is bound to — its connectors, its data sources, its connections. They say nothing whatsoever about a string a maker typed into a formula. The only place that string exists is the app's own source.

Why the project plan never catches this

The pattern across all three is the same: the information that decides whether a migration succeeds is not in the place everybody looks.

The admin centre gives you a list of apps and flows, with owner, environment and modified date. It will not tell you that app A calls flow B, that flow B is bound to a personal connection belonging to someone in finance, that neither is in a solution, and that the app's main button opens a library in the tenant you are leaving.

You can get all of it by hand. Export each app, unpack the package, read the formulas, cross-reference the flow definitions against the connection list, repeat a few hundred times. We have done it that way. It takes weeks, it gets done once at the start, and it is stale by the first cutover.

What we do instead

This is the specific gap Power Insights was built to close, and it is why its migration tooling looks the way it does. Four things carry most of the weight.

Which connection is used by which app

The assessment reads every environment and resolves the chain: app → connector → connection → the account that connection authenticates as. It also runs the other way, so opening a connection shows everything downstream that would break if it went away.

That is the list that tells you how much of the estate is one leaver away from stopping, and it is the list you need before deciding which connections have to exist in the target first. Custom connectors are called out separately, because they have to be rebuilt on the far side before anything that binds to them will import at all.

Which apps have something hardcoded inside them

Because the admin APIs cannot answer this, Power Insights reads the app packages themselves. You can search them for SharePoint references, for a hostname, for a Power BI workspace, or for any arbitrary string, and get back every app that contains it — exportable to Excel or CSV so it goes straight onto the remediation list. The same tooling finds flow actions by kind and reports the SQL server, database and stored procedure each step reaches.

In practice the useful query is the simplest one: search every app for the source tenant's hostname. Whatever comes back is the list of buttons that will silently point the wrong way after go-live.

Who had access before

Re-sharing is the step everyone forgets until the first morning after cutover, when the apps are in the target and nobody can open them. Power Insights exports the users and groups each app was shared with and at what level, so permissions get reconstructed deliberately rather than from the helpdesk queue. Sharing is read live rather than from the stored assessment, because it is the figure most likely to have moved since the last sync.

The same list does a second job: anything shared with the entire tenant is called out rather than counted — usually the moment somebody decides it should not be re-shared that way on the other side.

What depends on what

Starting from the apps you intend to move, the dependency view grows the list to what actually has to travel with them: the flows each app calls, read from the app's own data sources rather than from a spreadsheet; the connectors the selection binds to, ranked by how many objects bind to them; and the solution membership of everything involved, so objects that must move together end up in the same package.

That becomes a solution plan — what is already packaged, what has to be created, what needs adding to a solution that already exists — with a dry run that reports exactly what creating them would do and writes nothing.

Matching is by app id and environment name, never by display name. Two environments routinely hold apps called the same thing, and matching on the name quietly moves the wrong one.

The order that works

  1. Assess the tenant before the migration list is agreed. The list is an input to the plan, not the plan.
  2. Grow the list to its real dependencies — flows, connections, connectors, solution siblings.
  3. Search the app sources for the source tenant's hostname and anything else hardcoded. Fix those in the source, before export, while there is still a working environment to test in.
  4. Convert flows to connection references while they are being packaged, not after they have landed.
  5. Export the access list per app so re-sharing is a checklist rather than a scramble.
  6. Then move things — and track where each app has got to, because a migration runs for weeks and the question everybody asks on a Friday is which apps are where.

None of that removes the work. It removes the surprises, which is the part that costs the schedule.

Start from what the tenant actually contains

Power Insights inventories every environment, app, flow, connection, connector, solution and Dataverse table in your tenant, resolves the dependencies between them, and searches inside the app packages for the things the admin APIs cannot see. It is read-only, there is nothing to install, and the free plan assesses an environment without a card.

If the estate needs governing rather than moving, the governance side covers ownership, exposure, credentials and environment sprawl — including an honest comparison with Microsoft's CoE Starter Kit. And if you would rather we ran the migration with you, that is our migration service.

Power PlatformPower AppsPower AutomatePower Insights

Want to apply this in your tenant?

Book a free call with a LogiSam consultant — we will show you the quickest, safest way to do it on Microsoft 365.

LogiSam Assistant Guided help & instant answers

Answers come from this website. Privacy policy

↑↓ to navigate ↵ to open