Back to Blog
·VerseBlocks

What Actually Runs on a Dataverse Table

DataversePower PlatformDevelopment

Someone asks you to add a required field to Account. Easy. Twenty minutes. Then a flow starts failing at 2am and nobody can say why, because what actually broke was a plug-in registered on Update of a column you renamed, written by a contractor who left in 2023.

I have never opened a Dataverse environment and found one place that lists everything running on a table. It doesn't exist. All of that information is real and all of it is queryable. It's just spread across seven screens that nobody visits in the same afternoon.

So here's the actual list, and where each piece hides.

Seven places to look

Plug-in steps live in the maker portal under your default solution, or in the Plugin Registration Tool. Use the tool if you care about filtering attributes, because the maker portal won't show you those, and filtering attributes are usually the reason a step you thought was safe fires on every single save.

Real-time workflows are the classic ones. They still exist in far more environments than people admit, and they run on the same events plug-ins do. You'll find them in the Process table.

Cloud flows are the worst offender, because there is no view anywhere that says "flows that trigger on Account." You either open every flow and read its trigger, or you query the workflow table and parse the clientdata column yourself.

Business rules are in the form designer, one form at a time. They're also sneakier than they look, because a business rule has a scope. Entity scope runs server side on every write, including writes from integrations that never touch a form. All Forms runs client side only. Specific form runs only on that form. Two rules with identical logic and different scopes behave nothing alike, and the designer doesn't make that obvious.

Form scripts are in form properties, per form, per event. OnLoad, OnSave, and OnChange for each field. A table with twelve forms gives you twelve separate lists to read.

PCF controls are in control configuration, per field, per form. Same twelve form problem.

Duplicate detection rules and data quality rules sit in a completely separate admin area that most makers have never opened.

The order is the part people get wrong

Knowing what runs is half of it. Knowing when it runs is what actually saves you.

Dataverse executes synchronous logic in stages. Stage 10 is pre validation, and it runs before the database transaction starts. Stage 20 is pre operation, inside the transaction, before the record is written. Stage 40 is post operation, inside the transaction, after the write. Stage 30 is the main operation and it's reserved for the platform, so you can't register anything there.

Within a stage, steps run in rank order, lowest first. Two plug-ins with the same rank run in an order you don't control and shouldn't rely on.

Asynchronous steps go into the job queue and run later, and "later" is not guaranteed. If you have a plug-in that assumes an async step already finished, you have a bug that shows up under load and never in dev.

Real-time workflows interleave with plug-in steps in the same stages. If you've got both on a table, reading either list on its own gives you a false picture of the sequence.

This is where most "it works in dev but not in prod" tickets come from. The logic is the same. The order isn't, because prod picked up an extra step somewhere along the way.

So we built the view

We put a tool in the Power Platform ToolBox called Table Logic Map. Pick a table, and it reads all seven of those sources and shows you one list: plug-ins, classic workflows, cloud flows, business rules, form scripts, PCF controls and data rules, grouped by event and ordered by pipeline stage.

It's free, it runs on your machine against your own connection, and it exports to Markdown or JSON so you can paste the result into a change request or hand it to an AI agent.

Being straight about what it can't do. It reads what's registered, not what the code inside does. If a plug-in assembly has a bug, this won't find it. What it will tell you is that the assembly is there, that it fires synchronously on Update of the column you're about to change, and that it runs before the three other things you already knew about.

That's usually the sentence you were missing.

If you're about to change a table

Read the whole list first, not just the part you remember. Check the business rule scopes, because entity scoped rules fire on integration writes and people forget they exist. Look at filtering attributes on every synchronous step, since a step with no filtering attributes runs on every save of every column. And write down the order before you change it, so you have something to compare against when something breaks.

None of this is hard. It's just tedious enough that almost nobody does it, which is why the same outage keeps happening.