If you’ve been following along with the Revit Cloud Upgrade series, you should now be comfortable with reading the Test Upgrade Report properly, not just scanning it, but understanding what actually blocks an upgrade and what doesn’t.
That’s great if the project is small and only has a few models, but it can be very difficult to manage on larger projects with potentially hundreds of models, so today, we look at a workflow that can help scale your judgement without losing the plot.
A Workflow for Triage and Decision-Making
Revit upgrades on large projects can become problematic when teams can’t tell which warnings actually matter, which ones repeat across dozens of models, and which can safely be ignored. While Autodesk Construction Cloud’s Test Upgrade Report contains everything you need, it doesn’t help you decide what to do next.
Once you’re past a dozen models, the HTML report stops being a review tool and becomes a wall of text. At that scale trying to prioritise resolution steps becomes a task in itself as you try to distinguish the signal from the noise.
To help with cutting through that noise, I use Jupyter Notebooks to process the HTML into something more meaningful that allows you to make more informed decisions on how to tackle your models prior to committing to the upgrade. Below is an example of my Python + Power BI workflow that I use to turn those reports into something you can triage, stage, and hand off with confidence.



A Jupyter Notebook is an interactive computing environment that combines code, visualizations, and explanatory text into a single, living document. Rather than working in isolated scripts, notebooks organize your work into individual “cells” that can be executed independently. Each cell might contain a calculation, a plotted graph, or a written annotation, with its output rendered directly beneath it. This modular, live-updating format lets you explore data, test design or structural assumptions, and document your process step-by-step in real time. Because every instruction and result stays linked and easily versionable, notebooks are widely used for reproducible analysis, rapid prototyping, and sharing transparent, handoff-ready workflows.
The Core Problem with the HTML Report
The Test Upgrade Report isn’t really written for end easy end user analysis. You can end up with situations where the report repeats errors in the same family across multiple models, the same geometry failure hundreds of times across different families, mixes blocking failures with auto-resolved noise, meaning that it often doesn’t give an immediate sense of scale.
You’re left scrolling, skimming, and relying on gut feel.
Treat the Report as Raw Data
The first step is simple. Shift your mindset so that you’re not using the HTML report as the final product. It’s raw input.
Once you accept that, the workflow becomes straightforward. Python handles the extraction and cleaning. Power BI handles the exploration and decision-making allowing you and your team to focus on fixing the actual problems.
How It Works
The notebook itself is straightforward:
- Extract structured data from ACC’s HTML reports – ACC wraps upgrade results in an HTML page with the actual data embedded as JSON data. The notebook parses that out, giving you a clean, repeatable data source instead of something you have to manually dig through each time.
- Isolate core error patterns from verbose messages – Revit wraps each error in a template that includes the family name and status. The normalisation pipeline extracts just the underlying error, so “Base sketch for extrusion is invalid” is recognized as the same issue whether it came from a switchboard or a pipe fitting. This is what makes it possible to count and rank error types meaningfully.
- Classify severity with a conservative rule set – Deletions, failed upgrades, and unrecoverable geometry failures get flagged as Critical. Auto-resolved warnings stay Informational. If it’s flagged Critical, it can materially affect the upgrade outcome. If it’s not, it probably won’t.
- Reconstruct into relational tables for Power BI – The nested JSON gets turned into linked tables (issues, elements, model summaries, resolutions) and exported as a multi-sheet Excel file. You could load the raw JSON into Power BI directly, but you’d lose the error normalisation, severity classification, and resolution mapping. The notebook does that upstream so Power BI just displays what matters.
- Map errors to a persistent resolution dictionary – Each unique Critical error links to a standardized troubleshooting checklist. Once you figure out a fix, that resolution carries forward to every future project. New error types can optionally draft resolution steps via an LLM, but everything gets cached locally in an Excel file. The LLM is a convenience, not a dependency. All core analysis works without it.
Why Power BI Changes the Conversation

Once the cleaned data lands in Power BI, the workflow stops being about “reviewing” and becomes about making decisions. Instead of scrolling through hundreds of lines, you can filter by severity, slice by model or family, and group by core error type in seconds. You can instantly see whether three hundred warnings are coming from one broken legacy family or three hundred different problems. You can identify which models failed outright, which ones will be impacted most by deleted elements, and which issues should be fixed in your content libraries before they ever touch a project file.
The Resolutions tab is where the workflow pays off. You can generate the solutions manually based on your company best practice, or in the example, I’ve used a web enabled LLM to automatically generate potential solutions. The idea here is that you are replacing vague warnings with concrete next steps, so BIM coordinators and modelers know exactly where to start in Revit. The idea isn’t to use Power BI to replace your judgment, the idea is to stop you from wasting it on noise.

What This Workflow Does Not Do
The tool never touches raw geometry, never guesses at design intent, and never auto-applies changes. The optional LLM component only drafts resolution steps after the Python script has already processed the HTML. and only does so once per error type. Human review still decides what’s acceptable. The tool just helps to communicate the errors consistently and gives you a structured place to start.
The biggest shift this workflow creates is behavioural. Instead of:
“There are hundreds of warnings. This feels risky.”
You get:
“Three core errors account for most of the high-severity issues. All trace back to legacy families.”
Instead of:
“We need more time because upgrades are unpredictable.”
You get:
“Two models failed outright. Five models need a good cleanup to not impact deliverables post upgrade. We’ll fix families first, then stage the upgrade.”
The Catch? You Still Have to Understand the Report
This only works if you already know what the Test Upgrade Report is trying to tell you. If you don’t understand why deletions matter more than raw warning counts, or why some failures are contextual, then Python and Power BI will only confuse you in a prettier format.
The HTML report tells you what will happen. Python and Power BI help you decide what to do about it.
The full notebook and Power BI template are available in the GitHub repository.
If you’re running upgrades across multiple models, I’d be interested to hear what bottlenecks you hit when moving from the HTML report into Revit. What’s the one thing that usually slows your team down, and how have you been working around it?



No Comments