"Move the solutions" assumes there is a solution: getting work out of a developer environment

The official guidance for saving a developer environment before 15 December is to enable Managed Environments on it or move the solutions out. Both assume the work is in a solution, and in a personal developer environment it usually is not. Here is what is actually involved, and the dependencies that break quietly rather than loudly.

LogiSam··9 min read

If you are keeping a developer environment past 15 December 2026, Microsoft gives you two routes: enable Managed Environments on the environment, or move the solutions to an environment that is supported. The second is the cheaper one for most of what you will find, and it contains an assumption that does not hold in the place this change actually affects. Personal developer environments are precisely where work is least likely to be in a solution.

Why the work is not in a solution

A solution is the unit of export and import. It carries apps, flows, tables, connection references and environment variables together, and it is the only thing that carries them between environments as a set. But an app has to be created inside a solution, or deliberately added to one afterwards — it does not arrive in one by default. The maker portal offers a blank canvas first, and a flow built from a template lands outside every solution.

In a developer environment, where the audience is one person and there is no release process, almost nobody takes that step. So when you come to export, there is nothing to export: no solution, and therefore no package. Each app can still be exported on its own as a .msapp or a .zip, one at a time, through a different dialog — but what comes out does not import into a solution, does not use connection references, and has to be re-shared and re-bound by hand at the other end.

The first question, then

Not "which environments do we convert" but "which apps and flows have no solution to move?" That number changes the plan, because every object on that list needs a solution created and the object added to it before a migration can be a migration rather than a rebuild.

Solution membership is not returned by the PowerApps or Flow admin APIs. It lives in Dataverse's solutioncomponents table — cloud flows at component type 29 keyed by workflowidunique, canvas apps at 300, model-driven apps at 80. An object with no row there belongs to no solution. The mechanics of converting them in bulk, including what Add-AdminFlowsToSolution can and cannot do, are the subject of a companion article in this blog on why "no solution" is the most expensive answer in a migration.

The dependencies that break at run time, not at import

A failed import is annoying but honest: it tells you something is missing. The expensive failures are the ones that import cleanly and then do not work, because nothing in the package declared the dependency in the first place.

  • A canvas app calling a flow. The app records the called flow as a Power Fx identifier — a name, not an id. Move the app without the flow and the import succeeds; the button fails the first time somebody presses it. The app's package does not list the flow as a requirement.
  • A flow inside the solution calling a flow outside it. The export takes the first and silently leaves the second behind. The child flow still exists in the environment that is about to be deleted.
  • Hard-coded SharePoint site URLs and SQL connection strings, written into the app or flow definition rather than held in an environment variable. They point at the right thing today and at nothing in the target environment, and they are not visible in any dependency view the platform offers.
  • Connections rather than connection references. A non-solution flow binds a connection directly, owned by one person. Converting the flow into a solution does not convert its connections into connection references; that stays a per-flow edit in the designer, or an accepted limitation that the import wizard re-binds.
  • Custom connectors and Dataverse tables that live only in the environment being retired. A custom connector is a solution component like anything else, but only if somebody adds it.
  • Desktop flows, which exist only in Dataverse and are not eligible for the cloud-flow conversion route at all. If the finance team has built unattended bots in a developer environment, they need adding to the solution directly.

Premium connectors, and the licence consequence

Worth separating out, because it decides between the two remediation routes. Any app or flow binding a premium connector — SQL Server, Dataverse-as-a-connector, HTTP, Azure services, most third-party connectors — needs a licence that covers it for every user who runs it. In an unmanaged developer environment that cost has been invisible, because the Developer Plan covered the maker building alone.

It stops being invisible in both directions. Convert the environment to managed and Managed Environments use rights are not included in the Developer Plan, so every user of those apps needs a premium licence. Move the work to a production environment and the same licensing applies to whoever ends up using it there. Either way, knowing which objects bind premium connectors before you choose is the difference between a budget and a surprise.

What you need per object, before moving anything

  1. 1Which solution it belongs to, or that it belongs to none.
  2. 2Which flows it calls, and whether each of those is in the same solution.
  3. 3Which connectors it binds, and the concrete endpoint behind each one — the site, the list, the server, the database.
  4. 4Whether any of those endpoints is hard-coded rather than held in an environment variable.
  5. 5Who owns it, who it is shared with, and whether those accounts still exist.
  6. 6Whether it binds a premium connector, and how many people would need a licence.

None of that is in one place in the platform. Solution membership is in Dataverse, sharing is on the apps and flows APIs, owner names are in Microsoft Graph, connector endpoints are inside the app and flow definitions, and the app-to-flow relationship is a Power Fx identifier buried in the canvas app package. Assembling them is the whole job, and it is why the triage takes longer than the move.

An order that works

  1. 1List every object in the affected environments, and mark which have no solution.
  2. 2Resolve the dependencies — app to flow, flow to child flow, connector to endpoint — so each object travels with what it needs.
  3. 3Create the destination solution with a publisher you control.
  4. 4Add the apps, desktop flows and custom connectors as components; convert the cloud flows in batches and collect the refusals.
  5. 5Fix the refusals, which are usually a flow already sitting in another unmanaged solution and needing removal there first.
  6. 6Export, import, then re-bind connections and re-share in the target. Expect this step, rather than hoping it is unnecessary.

The step most plans skip is the second one, and it is the only one that prevents an import that succeeds and an app that does not work.

Questions

Can I export a canvas app that is not in a solution?
Yes, one at a time, as a package or a .msapp file. What comes out does not import into a solution, does not use connection references, and needs re-sharing and re-binding by hand — which is why it does not scale past a handful of apps.
Does adding a flow to a solution break it?
No. The administrator conversion route moves a non-solution cloud flow into a solution in place: the flow keeps its id, its run history and its connections. Desktop flows are not eligible for that route and have to be added as solution components directly.
Why does my app import fine but fail when a button is pressed?
Most often because the app calls a flow that did not come with it. A canvas app records a called flow as a Power Fx identifier rather than an id, so neither the export nor the import can tell that the flow is missing.
Will converting flows into a solution also create connection references?
No. Converting changes solution membership, not binding. Replacing a direct connection with a connection reference is a per-flow edit in the designer, or something the import wizard re-binds in the target environment.
How do I know which objects are not in a solution?
Read Dataverse's solutioncomponents table per environment — cloud flows at component type 29, canvas apps at 300, model-driven apps at 80 — and treat anything with no row there as non-solution. It is not available from the PowerApps or Flow admin APIs.
move solutions between environmentsnon-solution Power AppsPower Platform developer environment migrationcanvas app dependenciessolution aware flowsPower Platform migration
"Move the solutions" assumes there is a solution: getting work out of a developer environment · Power Insights