· Fabric agent demo

Build recap

A banking Power BI report, built by an AI agent — as reviewable code.

Over one working session, Claude Code took an empty folder to a validated, three-page Branch & Channel Performance report on Microsoft Fabric — authored entirely as diff-able PBIP (TMDL + PBIR), profiled against a 100% AI-generated dataset, and opened cleanly in Power BI Desktop. This is the story: what went in, how it went, what broke, and what it cost.

Session 16 Jun 2026 Agent Claude Opus 4.8 (Claude Code) Stack Power BI PBIP · Microsoft Fabric Opens & validates in Desktop
1
Report shipped
10
Model tables
22
DAX measures
3 / 31
Pages / visuals
183
Source files profiled
0
Validation errors

Scope

What went in, what came out

The brief, the raw materials, and the deliverables.

Input

  • Brief — design a repo for many reports over time; start with a banking report; each report keeps its own dataset, document, and dictionary.
  • Starting point — an empty repo on Windows, plus the Skills-for-Fabric and Power BI agentic skill plugins.
  • Data (mid-session) — a synthetic "BankDIAD" sample: transactions, NPS, targets, balances, and dimension workbooks, monthly across 2023–2025.

Output

  • Repo system — conventions, a report lifecycle, a shared Datapot theme, templates, and a registry.
  • Semantic model — a TMDL import model: 3 facts, 6 dimensions, 22 measures, 11 relationships.
  • Report — three PBIR pages (Overview, Channel Performance, Branch Scorecard); 31 visuals; opens & refreshes in Desktop.
  • Docs — dataset contract, data dictionary, data profile, model design, and a build log.

Process

How it happened

Six phases — a real sequence, each gated by a check or a decision.

1
Research

Learn the toolkit and the format

Read the Skills-for-Fabric structure and recommended flow, plus the exact PBIP / TMDL / PBIR rules from the installed plugins.

2
Design

Scaffold the multi-report repo

One self-contained folder per report — dataset, dictionary, docs, and the PBIP project — plus conventions, a shared brand theme, and templates.

3
Draft

Propose a model, then pause

Built a first-pass star schema and a minimal Overview page — then asked the right question: profile the real data before committing to the model?

4
Profile & reconcile

Rebuild the model to the real schema

Profiled the pasted BankDIAD files and rebuilt the model to match reality. Balance and loan tables were set aside for future reports.

5
Debug

Make it open in Power BI Desktop

The longest phase — a chain of errors that only Desktop's strict parser raised, while every command-line validator reported success. See the log below.

6
Confirm & build

Sign off the design, then build pages 2 & 3

Confirmed the purpose, story, and layout first, then built Channel Performance and Branch Scorecard — 23 visuals across the two pages.

The interesting part

The debug log

Every blocker hit while getting the project to open. All four were invisible to tmdl-validate, pbir validate, and validate_pbiponly Power BI Desktop caught them.

A description comment broke the model Resolved
TMDL Format Error: InvalidLineType — Unexpected line type: Empty · ./relationships, line 2
Root cause
A /// description followed by a blank line.

TMDL requires a description to sit immediately above the object it documents.

Fix
Removed the orphaned comment.

Audited all 14 TMDL files for the pattern; normalized to LF, UTF-8, no BOM.

Comments aren't allowed at the TMDL root Resolved
TMDL Format Error: InvalidLineType — Unexpected line type: Other · ./expressions, line 1
Root cause
// comments are rejected outside an expression body.

Introduced while fixing the first error — the parser does not accept bare comments at the root.

Fix
Removed all root-level comments.

Descriptions live in the data dictionary instead; the rule is now recorded in the repo's agent guide.

A theme property was missing — and it cascaded Resolved
Required property 'reportVersionAtImport' was not included in /themeCollection of report.json
Root cause
Theme entries missing a required field.

Desktop rejected report.json, which cascaded into a misleading "the report has no pages".

Fix
Added reportVersionAtImport to both themes.

The page errors disappeared — they were a side effect, not a real page problem.

The breakthrough: folder names with a dot Resolved
ActivePageName not found · The report has no pages. Reports must have at least one page.
Root cause
Page folders named Overview.Page.

PBIR folder names must be word characters only. The dot makes them non-compliant, so Desktop silently ignores the folder — while every command-line tool still "saw" three pages.

Fix
Renamed to Overview (no suffix).

Confirmed against Microsoft's PBIR documentation. This was the real blocker the whole time.

Cost

What it cost

Rough estimates — confirm the exact figure with /cost in Claude Code.

$18–30 est.

Wall-clock ≈ 3–4 hours of interactive work, including round-trips to test in Power BI Desktop. Most of the spend — and most of the time — went to phase 5, the debug chain, not to modeling or layout.

This is an estimate, not a bill. Token usage depends heavily on prompt caching. Run /cost in the session for the real number.

How the estimate is built

Output tokens (TMDL, JSON, docs, replies)~100–140k
Input + cached context (heavy reads, re-runs)~3–5M
Opus 4.8 rate assumption (out / in)$75 / $15 per M
Cache reads (~10% of input rate)applied
Estimated total$18–30

Biggest driver: iterative Desktop debugging — pasting errors, reading references, re-validating. A reusable template would cut most of it.

Reuse

Prompts worth reusing

The inputs that actually moved the work forward — copy, adapt, reuse.

Kickoffsets scope and a reusable structure in one shot
Read the Skills-for-Fabric repo, understand the structure and recommended
workflow. Design this repo for multiple-report development. Start with the
1st report (banking). Each report should have its own folder, dataset,
document, and dictionary for future reference.
Quality gateprofile-before-model — prevented a wrong model
Should we wait for the sample data and profile it before starting the report?
Debug loopexact error text = fast, precise fixes
# Paste the verbatim Desktop error — Document, Line Number, Line
New bug, fix please:
TMDL Format Error: InvalidLineType … Document './expressions' …
Persistencekeeps the agent iterating to a clean open
Still errors, please fix till the end.
Design gatesign off intent before any visuals are built
Continue with the 2 remaining pages — but confirm the business purpose,
story, and layout with me first, before you build.

Takeaways

Lessons, and what to improve

What we would tell the next person building a PBIP report with an agent.

What we learned

  • Profile real data before you model.The domain-assumption schema did not survive contact with the real export. The first model was a proposal, not the answer.
  • Command-line validators are lenient; Desktop is the judge.Three tools reported success while Desktop still refused to open the file. Test in Desktop early.
  • "No pages" usually is not a page problem.It was a non-compliant folder name, and once a cascade from a bad theme property.
  • Paste the exact error every time.Document, line number, and line made each fix surgical instead of guesswork.

What to improve

  • Keep a known-good PBIP template.Clone a report that already obeys every Desktop rule instead of hand-authoring from scratch.
  • Add a "Desktop-strict" pre-commit check.Catch root comments, dotted page folders, missing theme properties, and BOMs before they reach Desktop.
  • Make profile-first a standard step.Bake the cycle — paste data, profile, reconcile, build — into the report lifecycle.
  • Use ASCII-only working paths.A non-ASCII clone path triggered false positives from a validation hook.

Go deeper

Explore the repository

Everything here is open source (MIT) and built on 100% synthetic data. Clone it, open the report, or read how it is organized.