Skip to content

[Power BI] Fix SkuMeterName column error in storage reports for FOCUS 1.2 exports - #2333

Open
Michael Flanakin (flanakin) wants to merge 5 commits into
devfrom
xe/issue-2332-de385a
Open

Michael Flanakin (flanakin) wants to merge 5 commits into
devfrom
xe/issue-2332-de385a

Conversation

@flanakin

Copy link
Copy Markdown
Collaborator

🤖 [AI] Fixes #2332

Problem

Storage reports fail to refresh with Expression.Error: The column 'SkuMeterName' of the table wasn't found when the export uses FOCUS 1.2.

Fix

In the Costs query, the FOCUS 1.2 branch replaced values in a column named SkuMeterName. FOCUS 1.2 names it SkuMeter, and the non-1.2 branch and the following Align12 step already use SkuMeter. Updated the 1.2 branch to match.

Testing

Not run (requires Power BI Desktop). Verified the column name against FocusCost_1.2-preview.json.

🤖 Generated with Claude Code

…OCUS 1.2 exports

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Copilot AI lite review requested due to automatic review settings September 21, 2026 06:11

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

else Table.AddColumn( InvoiceId, "PricingCurrency", each [x_PricingCurrency]),
SkuMeter = if Has12
then Table.ReplaceValue(PricingCurrency, null, each [x_SkuMeterName], Replacer.ReplaceValue, {"SkuMeterName"})
then Table.ReplaceValue(PricingCurrency, null, each [x_SkuMeterName], Replacer.ReplaceValue, {"SkuMeter"})

@RolandKrummenacher Roland Krummenacher (RolandKrummenacher) Sep 21, 2026 •

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The rename itself is right — SkuMeter is what FOCUS 1.2 emits, and it matches both the else branch and the Align12 step below.

While checking it I found the rest of the block has the same class of problem, so I pushed a follow-up commit here rather than leaving it for later. Details below.

I ran a real FocusCost export against a test subscription (dataVersion: 1.2-preview, 105 columns) and diffed the header. In a 1.2 export none of the three legacy columns exist:

column 1.0r2 1.2-preview
x_InvoiceId yes gone — promoted to InvoiceId
x_PricingCurrency yes gone — promoted to PricingCurrency
x_SkuMeterName yes gone — renamed to SkuMeter

Side note: the API rejects dataVersion: "1.2" outright ("Export data version: 1.2 is not supported"), so 1.2-preview is currently the only 1.2-shaped export that can be created.

ftk_Storage does no backfill for focuscost (CleanColumns = if data = "focuscost" then ExtractColumns else ...), so the available columns are exactly the union of what's in the files. A container holding only 1.2 exports therefore has none of the three, and the refresh fails at each [x_InvoiceId] and at Align12's columnsToSearch — the same class of error as #2332, one step later. Only a container that also holds older 1.0/1.0r2 files was fixed by the one-line change alone.

EnsureRenamedCols now adds whichever side is missing as a null column before Align12 copies values both ways, so 1.0-only, 1.2-only and mixed containers all work. Has12 is gone — the per-column checks replace it and it had no other caller.

Also pushed: a PowerQueryColumnNames lint rule, since nothing in CI runs Power Query and that is why the typo shipped. It checks that every columnsToSearch literal names a real column, and that references to version-dropped columns are guarded. Reverting the one-line fix makes it fail with got 'SkuMeterName'.

On testing: the lint rule and the column measurements are solid, but the query change itself is only statically verified — I could not open the project in Power BI Desktop to refresh it. Shared.Dataset declares two columns in AdvisorReservationRecommendations that differ only by case, properties.extendedProperties.region (line 107) and properties.extendedProperties.Region (line 383). The tabular model is case-insensitive, so loading the project fails with "Item 'properties.extendedProperties.Region' already exists in the collection" before any refresh happens. Same in the kql dataset. That is pre-existing and unrelated to this PR, but it blocks an end-to-end check — worth a separate look.

Separate doc bug fixed in this PR: docs-mslearn/focus/metadata.md listed x_SkuMeterName in the FocusCost 1.2-preview column table. The real export doesn't have it. The ADF mappings in Exports/schemas/focuscost_1.2*.json were already correct.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🤖 [AI][Claude] ✅ Implemented

Confirmed — the existing Has12 check only decides which column name is authoritative, not whether the legacy x_ column exists at all. Even on the Has12 branch, the code still does each [x_SkuMeterName] (and x_InvoiceId/x_PricingCurrency) to backfill nulls, so a 1.2-only export (no legacy columns) errors on the next accessor in the chain.

Added a backfill step before this block that adds any missing x_InvoiceId/x_PricingCurrency/x_SkuMeterName as null text columns when absent, so the existing Has12/Align12 logic works unchanged for 1.2-only, 1.0-only, and mixed containers. Doc fix in docs-mslearn/focus/metadata.md was already merged in a prior commit.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🤖 [AI][Claude] Update: while I was drafting a backfill fix, e7e11e0 landed with a more complete version — it removes Has12 entirely and backfills missing columns on both the 1.0 and 1.2 sides (my version only handled the 1.2-only case). Dropped my commit in favor of that one; nothing further needed here.

Roland Krummenacher and others added 3 commits September 21, 2026 08:49
Nothing in CI runs Power Query, so a mistyped column name in a .tmdl
partition ships and surfaces only as a refresh failure on a customer's
report. That is how issue #2332 happened: the FOCUS 1.2 branch of the
Costs query searched {"SkuMeterName"}, a column no FOCUS version emits.

Two static rules:

- Every columnsToSearch literal in Table.ReplaceValue must name a column
  that exists - from a Cost Management export schema, created by the
  query itself, or declared on the model table.
- References to columns FOCUS 1.2 drops (x_InvoiceId, x_PricingCurrency,
  x_SkuMeterName) need a Table.HasColumns or _exists guard, because
  ftk_Storage does no backfill for focuscost. The dropped set is derived
  from the export schemas rather than hard-coded, so a future FOCUS
  version updates the rule on its own. Scoped to focuscost partitions:
  the pricesheet and reservationtransactions datasets reuse some of
  these names legitimately.

Rule 2 baselines the three existing unguarded references in Costs.tmdl
as a ratchet. Verified the rule catches the original typo: reverting the
one-line fix fails rule 1 with "got 'SkuMeterName'".

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
The FocusCost 1.2-preview table listed x_SkuMeterName alongside the
SkuMeter column that replaced it. Verified against a real FocusCost
export (dataVersion 1.2-preview, 105 columns): x_SkuMeterName is not
delivered. The 1.0 and 1.0-preview(v1) tables keep the column.

The ADF mappings in Exports/schemas already had this right.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
The "Handle columns renamed in FOCUS 1.2 gracefully" block read
[x_InvoiceId], [x_PricingCurrency] and [x_SkuMeterName] unconditionally,
and Align12 passed all three as columnsToSearch. FOCUS 1.2 does not
deliver them - verified against a real export (dataVersion 1.2-preview,
105 columns): InvoiceId, PricingCurrency and SkuMeter are present, the
three x_ columns are not. ftk_Storage does no backfill for focuscost, so
a container holding only 1.2 exports has none of them and the refresh
fails with "The column 'x_InvoiceId' of the table wasn't found" - the
same class of error as #2332, just one step later.

EnsureRenamedCols now adds whichever side is missing as a null column
before Align12 copies values in both directions, so 1.0-only, 1.2-only
and mixed containers all work. Has12 is gone: the per-column checks
replace it and it had no other caller.

Lowers the PowerQueryColumnNames rule 2 baseline to zero.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Needs: Review 👀 PR that is ready to be reviewed

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Getting this error Expression.Error: The column 'SkuMeterName' of the table wasn't found. Details: SkuMeterName

4 participants