Build recap
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.
Scope
The brief, the raw materials, and the deliverables.
Process
Six phases — a real sequence, each gated by a check or a decision.
Read the Skills-for-Fabric structure and recommended flow, plus the exact PBIP / TMDL / PBIR rules from the installed plugins.
One self-contained folder per report — dataset, dictionary, docs, and the PBIP project — plus conventions, a shared brand theme, and templates.
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?
Profiled the pasted BankDIAD files and rebuilt the model to match reality. Balance and loan tables were set aside for future reports.
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.
Confirmed the purpose, story, and layout first, then built Channel Performance and Branch Scorecard — 23 visuals across the two pages.
The interesting part
Every blocker hit while getting the project to open. All four were invisible to tmdl-validate, pbir validate, and validate_pbip — only Power BI Desktop caught them.
TMDL requires a description to sit immediately above the object it documents.
Audited all 14 TMDL files for the pattern; normalized to LF, UTF-8, no BOM.
Introduced while fixing the first error — the parser does not accept bare comments at the root.
Descriptions live in the data dictionary instead; the rule is now recorded in the repo's agent guide.
Desktop rejected report.json, which cascaded into a misleading "the report has no pages".
The page errors disappeared — they were a side effect, not a real page problem.
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.
Confirmed against Microsoft's PBIR documentation. This was the real blocker the whole time.
Cost
Rough estimates — confirm the exact figure with /cost in Claude Code.
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.
| 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
The inputs that actually moved the work forward — copy, adapt, reuse.
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.
Should we wait for the sample data and profile it before starting the report?
# Paste the verbatim Desktop error — Document, Line Number, Line
New bug, fix please:
TMDL Format Error: InvalidLineType … Document './expressions' …Still errors, please fix till the end.
Continue with the 2 remaining pages — but confirm the business purpose, story, and layout with me first, before you build.
Takeaways
What we would tell the next person building a PBIP report with an agent.
Go deeper
Everything here is open source (MIT) and built on 100% synthetic data. Clone it, open the report, or read how it is organized.