Summary
Raising a model's CompatibilityLevel from 1604 to 1702 via te set makes the save-gate's DAX validation report DAX0002 circular-dependency errors on measures that are not circular, blocking the save. The errors are non-deterministic (different errors and counts on repeated, identical invocations), a standalone te validate on the same resulting 1702 model reports no errors, and the real AS/Fabric engine accepts and runs the model. So this looks like a false positive in the save-gate's dependency analysis, not a model defect.
Environment
te 0.5.2.11639 (public preview)
- Windows 11
- Fabric semantic model (Direct Lake on OneLake), TMDL serialization, source
compatibilityLevel: 1604 → target 1702
Steps to reproduce
- A model using ordinary measure branching, with numeric/hyphen-prefixed measure names, e.g.:
[Base] = SUMX ( Fact, ... )
[60-Aankopen] = CALCULATE ( [Base], Account[cat] = "60" ), [61-Diensten] = CALCULATE ( [Base], Account[cat] = "61" ), … [67-Belastingen]
[Totaal kosten] = [60-Aankopen] + [61-Diensten] + … + [67-Belastingen]
[Nettoresultaat] = [Totaal opbrengsten] - [Totaal kosten]
(None of these reference each other or themselves.)
- Model is at
compatibilityLevel: 1604.
- Run:
te set . -q Database.CompatibilityLevel -i 1702 --save -m <model>
Actual
Save is blocked. Run #1 output:
Validation: 9 error(s)
DAX0002 A circular dependency was detected. Measure [61-Diensten en diverse goederen] is referencing itself. in Totaal kosten
DAX0002 ... [61-Diensten...] referenced Measure [62-Personeelskosten] which has a dependency on Measure [61-Diensten...]. in Totaal kosten
... (9 total)
Error: Save blocked: this mutation introduced 5 DAX validation error(s). Use --force to save anyway.
Run #2 — identical command, same model:
Validation: 2 error(s)
DAX0002 ... Measure [67-Belastingen] is referencing itself. in Totaal kosten
DAX0002 ... [Nettoresultaat] referenced Measure [Totaal kosten] which has a dependency on Measure [Nettoresultaat]. in Nettoresultaat
Different measures, different counts, on identical input.
Why this is a false positive
- The named measures are simple
CALCULATE([Base], <column filter>) — no self- or mutual-reference exists; e.g. [61-...] is referencing itself and [61]↔[62] are not real.
- Non-determinism: a circular dependency is a fixed structural property of the dependency graph and cannot change between runs of identical input. 9 then 2 points to a racy/incomplete graph build.
- Standalone
te validate on the resulting 1702 model: No validation errors found (reproduced 4/4 runs).
- After
--force-ing the save, the model deploys to the live engine and every measure evaluates correctly — the engine sees no circular dependency.
Expected
The save-gate's post-mutation validation should be deterministic and should not report circular dependencies that don't exist and that neither standalone te validate nor the engine reports. Likely the dependency graph isn't fully settled before the circular check runs after a compat-level change.
Workaround
--force the save; confirm with standalone te validate and a deploy. The model is fine.
Summary
Raising a model's
CompatibilityLevelfrom 1604 to 1702 viate setmakes the save-gate's DAX validation reportDAX0002circular-dependency errors on measures that are not circular, blocking the save. The errors are non-deterministic (different errors and counts on repeated, identical invocations), a standalonete validateon the same resulting 1702 model reports no errors, and the real AS/Fabric engine accepts and runs the model. So this looks like a false positive in the save-gate's dependency analysis, not a model defect.Environment
te0.5.2.11639 (public preview)compatibilityLevel: 1604→ target1702Steps to reproduce
[Base] = SUMX ( Fact, ... )[60-Aankopen] = CALCULATE ( [Base], Account[cat] = "60" ),[61-Diensten] = CALCULATE ( [Base], Account[cat] = "61" ), …[67-Belastingen][Totaal kosten] = [60-Aankopen] + [61-Diensten] + … + [67-Belastingen][Nettoresultaat] = [Totaal opbrengsten] - [Totaal kosten](None of these reference each other or themselves.)
compatibilityLevel: 1604.te set . -q Database.CompatibilityLevel -i 1702 --save -m <model>Actual
Save is blocked. Run #1 output:
Run #2 — identical command, same model:
Different measures, different counts, on identical input.
Why this is a false positive
CALCULATE([Base], <column filter>)— no self- or mutual-reference exists; e.g.[61-...] is referencing itselfand[61]↔[62]are not real.te validateon the resulting 1702 model:No validation errors found(reproduced 4/4 runs).--force-ing the save, the model deploys to the live engine and every measure evaluates correctly — the engine sees no circular dependency.Expected
The save-gate's post-mutation validation should be deterministic and should not report circular dependencies that don't exist and that neither standalone
te validatenor the engine reports. Likely the dependency graph isn't fully settled before the circular check runs after a compat-level change.Workaround
--forcethe save; confirm with standalonete validateand a deploy. The model is fine.