Rules / Error Prevention
Expression-reliant objects must have an expression
What it checks
Measures, calculated columns, and calculation items whose expression is empty.
Each finding names the object: a measure as [Total Margin], a calculated column as 'Sales'[Margin], and a calculation item by its own name with its calculation group beside it.
Example
Total Margin in the first snippet has nothing after its =. That is what an empty expression looks like in a TMDL file: the declaration is followed by another declaration at the same indentation, so nothing beneath it becomes the expression.
table Sales
column Amount
dataType: decimal
sourceColumn: Amount
column Cost
dataType: decimal
sourceColumn: Cost
measure 'Total Margin' =
measure 'Total Sales' = SUM(Sales[Amount])
formatString: #,0
table Sales
column Amount
dataType: decimal
sourceColumn: Amount
column Cost
dataType: decimal
sourceColumn: Cost
measure 'Total Margin' = SUM(Sales[Amount]) - SUM(Sales[Cost])
measure 'Total Sales' = SUM(Sales[Amount])
formatString: #,0
Why it matters
Without an expression the object cannot be evaluated: a measure returns nothing, a calculated column is empty, and a calculation item does nothing. Depending on the engine version the deployment fails outright, and the error points at the object without saying why.
How to fix it
Write the DAX, or delete the object. In Power BI Desktop, select the measure in the Data pane and type the expression in the formula bar, or right-click it and choose Delete from model; a calculated column takes the same two routes from the same pane, and a calculation item is edited in the calculation group's own view. In the TMDL file the expression is whatever follows the =, either on the declaration line or in the block indented beneath it, so measure 'Total Margin' = SUM(Sales[Amount]) - SUM(Sales[Cost]) is the whole repair. Where the object is not wanted, remove its measure, column, or calculationItem block instead.
When to ignore it
There is no case for keeping one. An object with no expression returns nothing wherever a report puts it, and the deployment may refuse it outright. A measure left blank as a placeholder while the work is unfinished is the closest thing to an exception, and giving it a body of BLANK() costs nothing and keeps the model valid in the meantime.
To ignore this rule on one object, add annotation pbiplint.ignore = EXPRESSION_RELIANT_OBJECTS_MUST_HAVE_AN_EXPRESSION under the object in its TMDL file. Power BI Desktop keeps the annotation. To turn the rule off for a whole project, set "EXPRESSION_RELIANT_OBJECTS_MUST_HAVE_AN_EXPRESSION": "off" under rules in pbiplint.config.json.
Quirks
- An expression of only whitespace counts the same as no expression at all.
- The block that follows a
=is taken whole, before any property beneath the declaration is read. AformatStringline written directly under a declaration whose=has nothing after it becomes that object's expression rather than its format string, so the rule stays quiet andPROVIDE_FORMAT_STRING_FOR_MEASURESreports the measure instead. An expression is empty only when the declaration is followed by a line indented no further than the declaration itself.
Related rules
DATA_COLUMNS_MUST_HAVE_A_SOURCE_COLUMNmakes the matching test on a data column, which takes its values from the partition query instead of an expression.PROVIDE_FORMAT_STRING_FOR_MEASURESis the rule that reports the measure when a property beneath an empty declaration is swallowed into the expression, as the quirks above describe.UNNECESSARY_MEASURESreports a hidden measure that no expression references, so deleting an empty measure that is also hidden clears both.
Ported from Microsoft's Best Practice Analyzer ruleset (opens in a new tab).
Check a model for this Improve this page (opens in a new tab)