PBI Fixer v2: From 11 Fixers to a Full Power BI Development Environment

PBI Fixer v2 Report Explorer with IBCS Variance

A few weeks ago, I published the first PBI Fixer article. It had 11 fixers — 5 for reports, 6 for semantic models — and a single promise: pbi_fixer(). One line of Python in a Fabric Notebook, and your reports get better.

That promise still holds. But the tool behind it has become something I did not anticipate. Built on top of Semantic Link Labs by Michael Kovalsky, which provides the core APIs that make all of this possible, the PBI Fixer has grown from a simple fixer into a full development environment.

45+ 12 19 0 1
Automated Fixers Interactive Tabs BPA Auto-Fix Rules License Cost Line of Python

What started as a fixer grew into a full Power BI development environment — a Semantic Model Explorer, a Report Explorer, a Memory Analyzer, a Perspective Editor, a Translations Editor, a Model Diagram generator, a Prototyping tool, BPA analyzers on both the model and report layer, a Delta Analyzer, and genuine IBCS implementation. All inside a Fabric Notebook. All driven by the same pbi_fixer() function call.

This article is the deep dive. I will walk you through every major capability, explain the reasoning behind the design decisions, and — because a picture is worth a thousand words — show you the screenshots.

🌐 Visit the PBI Fixer website for a quick overview: actionablereporting.com/pbi-fixer

1. The Evolution — How We Got Here

The PBI Fixer is the fifth generation of my attempt to codify Power BI best practices into reusable automation. Each generation taught me something that the next one built on:

2023 — Power BI Pimp Script (C# script): A single C# script for an external tool that automated calendar tables, measure tables, and calculation groups. The idea that best practices should be one-click actions, not documentation you read and then forget.

2024 — 80+ C# Macros: The Pimp Script expanded into a full library — 80+ macros organized by category, integrated with Stream Deck shortcuts. But still local, still C#, still semantic-model-only.

2025 — PBI Fixer PowerShell Edition (9 fixers): The first tool that touched both the report layer and the semantic model. PowerShell scripts that downloaded all reports from a workspace, replaced pie charts, applied themes, fixed page sizes, and re-uploaded them. Powerful, but fragile: Windows file dialogs, local execution, the report format was still opaque binary.

February 2026 — pbi_fixer() v1 (11 fixers): The move to the cloud. The introduction of the PBIR format and Fabric’s connect_report() API made it possible to read and modify report definitions programmatically — in a notebook, without downloading anything. 11 fixers, an ipywidgets UI, scan/fix/scan+fix modes. No local tools, no downloads, just pbi_fixer().

Now — PBI Fixer v2 (45+ fixers, 12 tabs): The current version. Not just fixers anymore — a complete development environment. The moment I realized that the same infrastructure (connect_report for PBIR, connect_semantic_model for TOM, ipywidgets for the UI) could power interactive exploration, editing, and analysis, the scope expanded naturally.

2. Getting Started — Still One Line

Before I dive into the tabs and features, let me make sure you can actually run this. It is still two cells in a Fabric Notebook:

# Cell 1: Install (run once per session, takes ~1 minute)
%pip install git+https://github.com/KornAlexander/semantic-link-labs.git@feature/pbi-fixer-ui

# Cell 2: Launch
from sempy_labs import pbi_fixer
pbi_fixer()

That is all. The interactive UI renders in the cell output. Type your workspace name, report name, and you are in.

You can also pre-fill the workspace and report:

# Load specific reports (comma-separated)
pbi_fixer(workspace="My Workspace", report="Sales Dashboard, Finance Report")

# Load ALL items in a workspace
pbi_fixer(workspace="My Workspace")

⚠️ Note: The PBI Fixer currently lives in a fork of Semantic Link Labs. It is not part of the official package yet — we’re evaluating if it makes sense. Once (if) it gets merged, the install becomes a true one-liner: just %pip install semantic-link-labs. Until then, use the fork URL above.

Prerequisites

  • A Microsoft Fabric capacity (F2 or higher, or a trial capacity)
  • A Fabric Notebook in your workspace
  • Reports in PBIR format for report fixers (the tool detects PBIRLegacy and can convert)
  • XMLA read/write enabled at the tenant level (required for semantic model operations)
  • Large semantic model storage format enabled in workspace settings (required for XMLA write)

3. Report Explorer — See Your Report, Fix Your Report

Report Explorer

The Report Explorer: tree view of pages and visuals with live embedded preview and fix actions

The Report Explorer is where most report-focused work happens. It loads your report’s PBIR definition and renders a navigable tree: Report → Pages → Visuals. Select any visual to see its properties — chart type, data fields, formatting. There is a live embedded preview panel so you can see what the visual looks like while editing its properties.

The key feature is the action dropdown at the top. This is where all 15 report fixers live:

# Fixer What It Does
1 Fix Pie Charts Replaces pie charts with clustered bar charts
2 Fix Bar Charts Removes axis clutter, adds data labels, removes gridlines
3 Fix Column Charts Same clean-up applied to column charts
4 Fix Line Charts Standardized line chart formatting
5 Fix All Charts Unified formatting pass across all chart types
6 Column → Line Converts column charts to line charts
7 Column → Bar (IBCS) Converts column charts to horizontal bar charts
8 Fix IBCS Variance End-to-end IBCS variance implementation
9 Fix Page Size Upgrades default pages to Full HD (1080×1920)
10 Hide Visual Filters Hides visual-level filters from consumers
11 Fix Visual Alignment Snaps misaligned visuals to consistent positions
12 Remove Unused Custom Visuals Cleans up unused custom visual registrations
13 Disable Show Items No Data Turns off “Show Items with No Data”
14 Migrate Report-Level Measures Moves report-level measures to the semantic model
15 Convert to PBIR Upgrades PBIRLegacy to PBIR format

Every fixer supports Scan mode — a read-only pass that tells you what would change without touching anything. This is essential for auditing: scan ten reports, get a findings list, then decide which ones to fix.

4. Semantic Model Explorer — Your Model Workbench

Model Explorer

The Model Explorer: object tree, DAX editing, data preview, with undo/redo tracking

The Model Explorer is a full workbench for your semantic model. It connects via XMLA and gives you a tree of everything: tables, columns, measures, hierarchies, relationships, calculation groups. Select any object to see its properties. Select a measure to edit its DAX expression and format string.

What sets it apart:

  • DAX editing — edit measure expressions directly, with a Save/Discard workflow
  • Create measures, calculated columns, and calculated tables — directly from the tree
  • Data preview — see Top 10 / Top 100 / All rows for any table with a single click
  • Auto-create measures from columns — the tool looks at SummarizeBy settings and generates explicit measures automatically
  • Add PY measures — select measures and get PY + ΔPY + ΔPY% generated for each
  • Undo / Redo — full change tracking, so you can roll back

This is not Power BI Desktop. It is not a replacement for external modeling tools. It is a focused tool that does the 80% of model editing work you actually need, running in the same notebook where you do your data engineering. No context switch. No download. No separate application.

5. IBCS — Where It Gets Interesting for Me

IBCS Variance Implementation

IBCS variance charts with proper green/red coloring, generated automatically from any existing bar or column chart

If you have read my other articles, you know that IBCS — the International Business Communication Standards — is a topic close to my heart. Clean, standardized business charts. No pie charts. No 3D effects. Horizontal bar charts for comparisons. Proper variance notation. Consistent scaling.

The PBI Fixer now has genuine IBCS implementation built in. And I don’t mean “it removes gridlines” — although it does that too. I mean end-to-end variance chart creation.

Here is what Fix IBCS Variance does, automatically, when you run it on a chart:

  1. Checks if a calendar table exists — if not, creates one (the same CalcCalendar from the semantic model fixers)
  2. Detects and builds the date relationship — finds the matching date column in your fact table and creates the relationship
  3. Generates PY measures — PY (prior year), ΔPY (absolute variance), ΔPY% (relative variance) for the measures used in the selected chart
  4. Adds error bar measures — creates the measures that drive the variance display
  5. Applies IBCS formatting — green/red coloring, proper axis configuration, data labels

A workflow that takes 30+ minutes by hand — done in seconds. The important thing: the resulting chart uses native Power BI visuals. No custom visuals, no marketplace dependencies.

The additional IBCS-aligned fixers complement this:

  • Column → Bar — flips vertical column charts to horizontal bar charts (IBCS prefers horizontal for categorical comparisons). Power BI Desktop does not have a “change orientation” button — the Fixer rewrites the visual JSON.
  • Fix All Charts — removes axis clutter, gridlines, adds data labels. This is what IBCS calls “decluttering” — making the data speak without chart junk.
  • Fix Pie Charts — replaces pie charts with bar charts. IBCS explicitly discourages pie charts.

These are not cosmetic tweaks. If you are serious about business reporting standards, this is the first time you can apply them programmatically across an entire report — not just read about what you should do, but actually do it with a function call.

6. Model BPA — 19 Rules, One-Click Auto-Fix

Model BPA

Model BPA: 19 best practice rules across 6 categories with Fix All / Fix Rule / Fix Row granularity

Best Practice Analyzers exist. External tools have them. Semantic Link Labs has run_model_bpa(). But here is the gap: most BPA tools tell you what is wrong. Some offer fix expressions for a handful of rules, but applying fixes at scale — across many rules, many objects, with granular control — is still cumbersome. And the majority of rules simply have no auto-fix at all.

The PBI Fixer’s Model BPA takes a different approach: every single one of its 19 rules comes with a one-click auto-fix button. And you can choose the granularity: fix everything with “Fix All”, fix a specific rule for all affected objects, or fix a single row. The underlying BPA engine in Semantic Link Labs was built by Michael Kovalsky — the PBI Fixer adds the interactive auto-fix layer on top.

Category Rules
🔢 Data Types Fix Floating Point Types (Double → Decimal)
📡 MDX Fix IsAvailableInMDX (False on non-attribute, True on key/hierarchy)
📝 Documentation Fix Measure Descriptions (auto-fill with DAX expression)
📊 Formatting Date format, Month format, Measure format, Percentage format, Whole number format, Flag column format, Sort Month Column, Data Category, Use DIVIDE(), Remove +0 prefix
🔗 Schema Hide Foreign Keys, Do Not Summarize, Mark Primary Keys
🏷 Naming Trim whitespace, Capitalize first letter

I cross-checked the PBI Fixer’s 19 auto-fixers against the community standard BPA rules: out of ~28 standard rules, only 7 have a FixExpression. Of those, just 4 overlap with the PBI Fixer’s rules (floating point types, IsAvailableInMDX, hide foreign keys, do not summarize). That means 15 of the PBI Fixer’s 19 auto-fixers — including all formatting rules, DIVIDE() correction, data categories, primary key detection, and naming fixes — have no equivalent auto-fix in the standard BPA ruleset.

7. Memory Analyzer — Vertipaq at Your Fingertips

Memory Analyzer

Column-level memory breakdown with color-coded percentage bars

The Memory Analyzer — built on top of SLL’s vertipaq_analyzer() by Michael Kovalsky — shows you where your model’s memory goes, broken down by tables, columns, partitions, relationships, and hierarchies. This is Vertipaq analysis built into the notebook, with color-coded size bars (red for columns taking >30% of total memory, orange for >10%, green for ≤10%).

For Direct Lake models, it also shows column residency and temperature — whether the data is hot (in memory), warm (cached), or cold (on disk). This is critical information for Direct Lake optimization that Desktop simply cannot show you.

8. Translations Editor — Multi-Language Metadata Management

Translations Editor

Grid view of all model objects × languages — add, edit, and manage translations in one place

If you work in a multi-language environment, this one is for you. The Translations Editor shows all model objects (tables, columns, measures) in a grid with a column for each language. You add a language from 20 built-in language codes, then edit translations directly in the grid — cell by cell. It is a manual process, but having all objects and all languages visible side by side makes it far more manageable than editing translations through the XMLA endpoint or third-party tools.

You can create new languages, delete existing ones, and see at a glance which objects are missing translations. No native Power BI tool gives you this kind of overview.

9. Perspective Editor — Visual CRUD for Perspectives

Perspective Editor

Expandable table tree with tri-state indicators: ● Full / ◐ Partial / ○ None

Perspectives are one of those features that everyone agrees are useful but nobody creates because the tooling is awkward. The Perspective Editor — inspired by the perspective management capabilities in SLL — makes it visual: an expandable tree with tri-state checkboxes. Select tables, columns, or measures for each perspective. Create new perspectives. Delete old ones.

If you are using Direct Lake and cache pre-warming (another fixer in the toolkit), perspectives are essential — the warm-up perspective defines exactly which columns to pre-load into memory.

10. More Tabs — Model Diagram, Prototyping, Delta Analyzer, Report BPA

Model Diagram

Model Diagram

Auto-generated SVG diagram with table boxes, columns, measures, and relationship lines

An auto-generated SVG diagram of your data model. Tables as boxes, columns and measures listed inside, relationships drawn as connecting lines with nearest-edge routing. This is not Power BI Desktop’s model view — it is exportable, embeddable, and generated in a notebook cell. Useful for documentation, architecture reviews, or simply getting a quick overview of an unfamiliar model.

Prototype & Excalidraw Export

Prototyping

Report page screenshots with auto-detected navigation and drillthrough paths

The Prototype tab captures every page of your report as a screenshot and detects page navigation links, buttons, and drillthrough connections between pages. You can export the whole thing as an Excalidraw file or SVG — giving you, for the first time, a bird’s eye view of your entire report on a single canvas.

I wrote a separate article about prototyping with AI where I used this feature to analyze a 35-page report and condense it to 18 pages in 10 minutes.

Delta Analyzer

Delta Analyzer

Parquet file and column chunk level inspection for Direct Lake optimization

If you are using Direct Lake, the Delta Analyzer is essential. Built on SLL’s delta table inspection capabilities by Michael Kovalsky, it inspects your lakehouse delta tables at the parquet file level — number of files, row groups, column chunks, column statistics, and cardinality. This is the data you need to decide whether your tables need V-Order optimization, repartitioning, or column type changes.

Report BPA

Report BPA

Report-level best practice analysis with auto-fix capabilities

While Model BPA focuses on the semantic model layer, Report BPA analyzes the report definition itself. It catches issues like unused custom visual registrations, “Show Items with No Data”, report-level measures (which should be in the model), and auto-converts PBIRLegacy before scanning.

11. Semantic Model Fixers — The Foundation

The 11 semantic model fixers use the XMLA endpoint and TOM (Tabular Object Model) to modify the data model directly. These are the original “one-click best practices” from the very first generation:

# Fixer What It Does
1 Discourage Implicit Measures Prevents implicit measure usage (required for calc groups)
2 Add Calendar Table 20-column calculated calendar with 3 hierarchies + auto-relationship
3 Add Measure Table Empty calculated table to centralize measures
4 Add Last Refresh Table M partition with refresh timestamp + measure
5 Add Units Calc Group Thousand & Million items with % skip logic
6 Add Time Intelligence Calc Group AC/Y-1/Y-2/Y-3/YTD + absolute/relative/achievement variances (21 items)
7 Measures from Columns Auto-create explicit measures from SummarizeBy settings
8 Add PY Measures PY + ΔPY + ΔPY% for selected measures
9 Setup Incremental Refresh Auto date column detection + policy configuration
10 Cache Pre-warm Direct Lake warm-up perspective + notebook generation
11 Prep for AI Descriptions, synonyms, linguistic metadata for Copilot readiness

Each of these runs through TOM and modifies the model’s metadata. Because XMLA write operations are irreversible (you cannot download the model as .pbix afterward), the UI requires an explicit confirmation before running semantic model fixers. Scan mode is always safe.

Cache Pre-Warm — Why This Matters for Direct Lake

Direct Lake is powerful because it reads directly from delta tables without importing data. But there is a cold-start problem: the first query against a model after a refresh (or after columns get evicted from memory) can be significantly slower because the data needs to be loaded from OneLake into the Vertipaq engine on demand. This is especially noticeable on models with many columns or wide fact tables.

The Cache Pre-warm fixer solves this by generating two things: a perspective containing only the columns that are actually referenced by DAX measures (so you are not warming up unused columns), and a notebook cell that runs a simple DAX query against that perspective — forcing the engine to pre-load those columns into memory. You can schedule this notebook to run right after your data refresh pipeline, so by the time users open the report, the data is already hot. Zero-effort, production-grade cache management.

Setup Incremental Refresh — Auto-Detection Done Right

Configuring incremental refresh manually is tedious: you need to identify the right date column, create RangeStart and RangeEnd parameters, modify the partition expression, and set the refresh window. The Setup Incremental Refresh fixer automates this entire process. It scans your model for date columns, lets you pick the right one, and configures the incremental refresh policy — including the historical window and the rolling refresh window. What used to be a multi-step, error-prone manual process becomes a single click with sensible defaults.

Prep for AI — Getting Copilot-Ready

Microsoft Copilot in Power BI works better when your semantic model has rich metadata: measure descriptions, column descriptions, synonyms, and linguistic schema info. But most models have none of this — descriptions are empty, synonyms are missing, and the model is essentially a black box to the AI.

The Prep for AI fixer generates all of this metadata automatically. It creates descriptions for measures (based on their DAX expressions), adds synonyms for columns and tables (common abbreviations and alternative names), and populates the linguistic schema that Copilot uses for natural language understanding. This is not just cosmetic — it directly improves the quality of Copilot-generated DAX queries and natural language answers. Going from zero to Copilot-ready in one click. Credit for the original idea and implementation goes to Lukasz Obst.

12. The Standalone API — Every Fixer is a Function

Everything you see in the UI is a Python function underneath. You do not need the interactive widget to use the fixers — you can call them directly in your own notebooks, scripts, or pipelines:

# Replace all pie charts in a report
from sempy_labs.report._Fix_PieChart import fix_piecharts
fix_piecharts("Sales Report", workspace="Production")

# Scan first (read-only)
fix_piecharts("Sales Report", workspace="Production", scan_only=True)

# IBCS variance — end to end
from sempy_labs.report._Fix_IBCSVariance import fix_ibcs_variance
fix_ibcs_variance("Sales Report", workspace="Production")

# Batch process multiple reports
reports = ["Sales", "Finance", "HR"]
for report in reports:
    fix_piecharts(report, workspace="Production")
    fix_page_size(report, workspace="Production")

This is where the AI and CI/CD story comes in. Because every fixer is a stateless function with a predictable signature (report, workspace, scan_only), an AI agent could generate the right call from a natural language prompt. A deployment pipeline could run scan-only passes as quality gates. A Fabric scheduled notebook could batch-fix formatting across all reports in a workspace overnight.

The functions are the same. The caller changes.

13. Built on Semantic Link Labs

I want to be clear about the foundation: the PBI Fixer is built on top of Semantic Link Labs, created by Michael Kovalsky. SLL provides the core abstractions — connect_report() for PBIR access, connect_semantic_model() for TOM/XMLA, and the notebook infrastructure that makes all of this possible in a Fabric environment.

Without SLL, the PBI Fixer would not exist. The fixer adds the interactive UI layer, the specific fix logic, the BPA rules, and the explorer/analyzer capabilities — but the engine underneath is Michael’s work. Credit where it is due.

The PBI Fixer is currently in a fork of SLL. We are evaluating whether it makes sense to merge it into the main repository. If that happens, %pip install semantic-link-labs would be all you need — the fork URL goes away, and it truly becomes one line.

14. What This Is Not

Let me be honest about the limitations:

  • Not a Desktop replacement — the PBI Fixer does not have a drag-and-drop report canvas. You cannot create new visuals from scratch (yet). It extends Desktop; it does not replace it.
  • Still beta — this is an early-stage tool with rough edges. Test on a non-production workspace first.
  • Requires Fabric — this runs in Fabric Notebooks. If you are on Power BI Pro without Fabric, this tool is not available to you.
  • XMLA write is irreversible — once you modify a model via the XMLA endpoint, you can no longer download it as a .pbix with embedded data. This is a platform limitation, not a PBI Fixer limitation.

That said — if you have Fabric, and you care about report quality, standardized formatting, and Best Practice adherence, I believe this is the most comprehensive tool available right now. And it is free.

15. “But Can’t AI Just Do This?”

Fair question. With Copilot in Fabric, ChatGPT writing Python, and agentic AI on the horizon — why build a UI tool at all?

Because AI is great at generating code when you know what to ask for. But most Power BI developers do not know that their model has floating-point columns, that 12 columns have SummarizeBy set to Sum, or that their report still uses pie charts. Discovery comes first — and that requires a structured UI that surfaces issues you did not know existed.

The PBI Fixer handles both sides. The interactive UI is for discovery: browsing a model tree, scanning for BPA violations, spotting memory hogs in the Vertipaq analysis, seeing which columns lack translations. You do not need to know what to look for — the tool shows you.

And once you know what to fix, the standalone API is where AI shines. Every fixer is a stateless Python function with a predictable signature. An AI agent can call fix_piecharts("Sales Report") just as easily as a human can click “Fix All”. A deployment pipeline can run scan_only=True passes as quality gates. A scheduled notebook can batch-fix formatting across an entire workspace overnight.

Today, you use the UI. Tomorrow, an AI agent runs the same functions. The PBI Fixer is not competing with AI — it is the toolkit AI will use.

16. What is Next?

The framework is open. Every fixer is an independent Python function with a consistent interface. Adding a new fixer means writing one function and wiring it into the UI. If you have an idea for a fixer — or you want to contribute — the GitHub repository is open.

This is mostly a free-time project — I work on it when I can, driven by curiosity and the feedback I get. If time allows, there is plenty more to build: more IBCS implementation, more BPA rules, video walkthroughs, and the ongoing evaluation of whether merging into Semantic Link Labs makes sense.

The first PBI Fixer article ended with:

The PBI Fixer is not just a tool — it is a shift in how we think about report quality. Instead of manually checking and fixing every visual property, every model setting, every best practice after the fact, we can now codify our standards and apply them at scale.

A few weeks later, that statement holds — but the scale has changed. From 11 fixers checking a few properties to a full development environment covering reports, models, BPA, memory, translations, diagrams, and prototyping. Still one line.

pbi_fixer()

If you try it, let me know on LinkedIn. Feedback — positive and negative — is what drives this project forward.

Leave a Reply