DAX-fout "A circular dependency was detected" (2026)
Power BI vindt een afhankelijkheidslus tussen DAX-objecten. Spoor de keten op en herstel berekende kolommen, measures, tabellen of relaties.
De melding “A circular dependency was detected” betekent dat een DAX- of modelobject zichzelf nodig heeft, of dat meerdere objecten via hun afhankelijkheden weer bij het begin uitkomen. Power BI kan daardoor niet bepalen welk object eerst moet worden berekend; breek één verwijzing in de lus en leid de uitkomst vanuit een onafhankelijke bron op.
Wat is een circulaire afhankelijkheid?
Power BI houdt voor berekende kolommen, measures en berekende tabellen bij welke objecten nodig zijn om een resultaat te berekenen. Dat vormt een gerichte afhankelijkheidsketen. Een geldige keten loopt bijvoorbeeld van een bronkolom naar een berekende kolom en daarna naar een measure.
Een cyclus loopt terug:
- kolom A heeft kolom B nodig;
- kolom B heeft measure C nodig;
- measure C heeft uiteindelijk kolom A nodig.
De formule waarin Power BI de fout toont is niet per se de oorspronkelijke oorzaak. Het laatste toegevoegde object kan alleen de terugweg hebben gesloten in een al bestaande keten. Controleer daarom de volledige lijst met objecten in de melding.
Deze fout is geen syntaxisprobleem. Kan Power BI je formule niet ontleden, gebruik dan de decoder voor “The syntax for ... is incorrect”. Een circulaire formule kan syntactisch volledig geldig zijn, maar het model heeft geen geldige volgorde om haar uit te voeren.
Welke objecten kunnen in de lus zitten?
De meest voorkomende deelnemers zijn:
- een berekende kolom die zichzelf gebruikt;
- twee berekende kolommen die elkaar direct of indirect gebruiken;
- measures die in een kring naar elkaar verwijzen;
- een measure in een berekende kolom, waardoor contexttransitie extra afhankelijkheden maakt;
- berekende tabellen die uit elkaar worden opgebouwd;
- een relatie die een berekende tabel of kolom terugkoppelt naar haar invoer;
- een Sort by Column-instelling terwijl de sorteerkolom uit de gesorteerde kolom is berekend.
Volgens de officiële uitleg over berekende kolommen kan Power BI een formule pas evalueren nadat de objecten waarvan zij afhankelijk is zijn berekend. De fout ontstaat zodra geen beginpunt meer overblijft.
Stap voor stap de circular dependency oplossen
1. Bewaar eerst een werkende kopie
Sla een kopie van het PBIX-bestand op voordat je relaties, sorteereigenschappen of meerdere berekeningen wijzigt. Verwijder niet meteen alle genoemde objecten. De foutmelding en de bestaande formules bevatten juist de aanwijzingen waarmee je de lus kunt reconstrueren.
2. Noteer de volledige objectketen
Schrijf ieder object uit de foutmelding in de getoonde volgorde op. Noteer per object:
- tabelnaam;
- objectnaam;
- type: bronkolom, berekende kolom, measure of berekende tabel;
- formule of modelinstelling;
- objecten waarnaar de formule verwijst.
Zo ontstaat een eenvoudige keten zoals Verkoop[Marge] → Verkoop[Omzet na korting] → Verkoop[Marge]. Zoek ook measures die tussen de zichtbare kolommen staan.
3. Zoek zowel expliciete als verborgen afhankelijkheden
Expliciete verwijzingen staan letterlijk in de DAX-formule. Verborgen afhankelijkheden kunnen ontstaan door:
- de automatische contexttransitie wanneer je een measure in rijcontext gebruikt;
CALCULATEin een berekende kolom;- een relatie waarvan een sleutel of tabel zelf berekend is;
- Sort by Column;
- een berekende tabel die een andere berekende tabel gebruikt.
Controleer dus niet alleen de formulebalk. Bekijk ook de modelweergave, relatie-eigenschappen en de sorteerkolom op het tabblad Kolomhulpmiddelen.
4. Bekijk de afhankelijkheidsgraaf met INFO.CALCDEPENDENCY
In een ondersteunde DAX Query View kun je de berekeningsafhankelijkheden opvragen:
EVALUATE
INFO.CALCDEPENDENCY()
De uitvoer bevat onder meer het object, het objecttype en het object waarnaar wordt verwezen. Zoek de objectnamen uit de foutmelding en volg de regels totdat een naam terugkomt. Een nieuwe formule die Power BI wegens de cyclus heeft geweigerd, staat nog niet in het opgeslagen model en moet je daarom handmatig naast de bestaande uitvoer leggen.
Deze functie is een diagnosehulpmiddel, geen reparatie. Microsoft vermeldt dat INFO.CALCDEPENDENCY alleen in DAX-query's kan worden gebruikt, schrijfrechten op het semantische model vereist en niet werkt wanneer Power BI Desktop live met het model is verbonden.
5. Kies één onafhankelijk bronobject
Bepaal welke invoer de zakelijke waarheid vormt. Dat hoort meestal een geïmporteerde bronkolom, een Power Query-kolom of een basismeter zonder verwijzing terug naar afgeleide objecten te zijn.
Laat daarna de afhankelijkheden maar één kant op lopen:
bronkolom → afgeleide kolom → measure
Een afgeleide kolom hoort de bronkolom niet opnieuw via een andere measure of berekende kolom te beïnvloeden.
6. Verplaats de berekening naar de juiste laag
Gebruik:
- Power Query voor statische rijlogica vóór het semantische model. In Import wordt die logica tijdens verversen uitgevoerd; in DirectQuery moet de transformatie naar de bron kunnen worden gevouwen en wordt zij onderdeel van de bronquery's;
- een berekende kolom voor een rijwaarde die je in assen, filters of relaties nodig hebt. In Import wordt zij bij verversen berekend en opgeslagen; in DirectQuery blijft zij ongematerialiseerd en gelden extra beperkingen;
- een measure voor een uitkomst die met rapportfilters moet veranderen;
- een berekende tabel voor een modeltabel die bij verversen uit onafhankelijke invoertabellen wordt opgebouwd.
Microsoft vergelijkt deze lagen in Calculation Options voor Power BI Desktop en beschrijft de opslagmodi bij berekende kolommen. De juiste laag kiezen maakt de afhankelijkheidsketen korter en voorkomt dat dynamische logica onnodig in een opgeslagen kolom terechtkomt.
7. Herstel en test één object tegelijk
Pas eerst het object aan dat de terugverwijzing maakt. Bevestig de formule en vernieuw het model. Controleer daarna de volgende afhankelijke berekening. Test tot slot:
- detailrijen;
- totalen;
- verschillende slicerselecties;
- een volledige gegevensverversing;
- relaties en sorteervolgorde.
Krijg je daarna een andere DAX-melding, open dan het overzicht met DAX-foutmeldingen en behandel die fout als een afzonderlijk probleem.
Oplossing 1: directe zelfverwijzing verwijderen
Deze berekende kolom probeert haar eigen waarde te gebruiken:
Netto bedrag =
Verkoop[Netto bedrag] - Verkoop[Korting]
Er bestaat geen startwaarde voor Verkoop[Netto bedrag]. Gebruik de echte bronkolom:
Netto bedrag =
Verkoop[Bruto bedrag] - Verkoop[Korting]
Let ook op een zelfverwijzing die achter een variabele of functie verstopt zit. Een andere variabelenaam verandert de afhankelijkheid niet als de expressie nog steeds de eigen kolom leest.
Oplossing 2: twee berekende kolommen één richting geven
In dit voorbeeld gebruiken twee kolommen elkaar:
Omzet na korting =
Verkoop[Bruto bedrag] - Verkoop[Marge]
Marge =
Verkoop[Omzet na korting] - Verkoop[Kosten]
Power BI kan geen van beide als eerste berekenen. Leid de eerste waarde af van bronkolommen en bouw de tweede daarop:
Omzet na korting =
Verkoop[Bruto bedrag] - Verkoop[Korting]
Marge =
Verkoop[Omzet na korting] - Verkoop[Kosten]
Nu is de richting Bruto bedrag en Korting → Omzet na korting → Marge. Als beide uitkomsten rechtstreeks uit dezelfde bronkolommen kunnen worden berekend, is dat vaak nog duidelijker.
Oplossing 3: measures vanuit één basismeter opbouwen
Measures kunnen eveneens een kring vormen:
Toeslag = [Totaal inclusief toeslag] * 0.05
Totaal inclusief toeslag = [Basistotaal] + [Toeslag]
Toeslag wacht op het totaal en het totaal wacht op Toeslag. Herschrijf de toeslag algebraïsch vanuit de onafhankelijke basismeter, zodat zij 5% van het inclusieve totaal blijft:
Toeslag =
DIVIDE(
[Basistotaal] * 0.05,
0.95
)
Totaal inclusief toeslag = [Basistotaal] + [Toeslag]
Gebruik één duidelijke basismeter voor iedere kernberekening. Afgeleide measures mogen die basis gebruiken, maar de basis mag niet terugverwijzen naar een afgeleide measure.
Oplossing 4: contexttransitie in een berekende kolom beperken
Een measure wordt normaal in filtercontext geëvalueerd. Roep je een measure vanuit een berekende kolom aan, dan vindt automatisch contexttransitie plaats: de huidige rij wordt naar filters vertaald. Daardoor kan de kolom afhankelijk worden van meer kolommen uit dezelfde tabel dan de korte formule laat zien.
Heb je de uitkomst alleen in visuals nodig, maak er dan een measure van. Een measure als:
Klantomzet = [Omzet]
reageert in een visual vanzelf op de klantfilter en hoeft niet als opgeslagen klantkolom te bestaan.
Moet je om een aantoonbare modelreden toch een waarde per klant opslaan, dan kun je de context alleen tot een gegarandeerd unieke basiskolom beperken:
Klantomzet bij verversen =
CALCULATE(
[Omzet],
ALLEXCEPT(
Klant,
Klant[KlantId]
)
)
Gebruik dit patroon alleen wanneer KlantId een echte unieke sleutel is en je de opgeslagen verversingsuitkomst bedoelt. CALCULATE en ALLEXCEPT zijn in DirectQuery niet ondersteund in berekende kolommen of RLS-regels, dus dit is daar geen geldige reparatie. De documentatie over CALCULATE beschrijft contexttransitie; ALLEXCEPT bewaart alleen de filters op de opgegeven basiskolommen.
Oplossing 5: Sort by Column losmaken van de afgeleide tekst
Stel dat Datum[Maand] op Datum[Maandnummer] moet worden gesorteerd. Bereken je Maandnummer weer uit Maand, dan ontstaat een terugkoppeling zodra de sorteereigenschap Maand → Maandnummer toevoegt.
Leid beide kolommen onafhankelijk af van de datum:
Maand = FORMAT(Datum[Datum], "MMMM")
Maandnummer = MONTH(Datum[Datum])
Stel daarna Maand in op Sort by Column Maandnummer. Beide kolommen hebben nu dezelfde bron en gebruiken elkaar niet. Zorg ook dat iedere maandnaam precies één maandnummer heeft. De actuele Microsoft-handleiding voor Sort by Column noemt bestaande afhankelijkheden en verschillende korrelniveaus als controlepunten.
Oplossing 6: berekende tabellen en relaties ontwarren
Een berekende tabel wordt bij verversen uit andere modeltabellen opgebouwd. Als tabel A tabel B gebruikt en B via haar formule of een modelrelatie weer van A afhangt, ontstaat opnieuw een lus.
Maak een gedeelde onafhankelijke bron:
- bouw beide tabellen rechtstreeks uit een geïmporteerde basistabel;
- maak een losse dimensie of brug in Power Query;
- laat slechts één berekende tabel van de andere afhangen;
- voorkom onnodige tweerichtingsrelaties en meerdere filterpaden.
Verander een relatie niet willekeurig naar veel-op-veel of beide richtingen om de foutmelding weg te krijgen. Relaties bepalen hoe filters door het model lopen. Gebruik de uitleg over modelrelaties in Power BI om kardinaliteit en filterrichting vanuit de gegevenskorrel vast te leggen.
Speciaal refreshgeval met SUMMARIZECOLUMNS
Microsoft documenteert een specifiek refreshprobleem voor berekende tabellen die SUMMARIZECOLUMNS gebruiken. Sinds een wijziging uit september 2024 kunnen nieuwe afhankelijkheden en een circular-dependency-fout ontstaan wanneer zulke tabellen tijdens verversen worden geëvalueerd.
Voor een groepering op Product en Regio ziet het oorspronkelijke patroon er bijvoorbeeld zo uit:
Samenvatting =
SUMMARIZECOLUMNS(
Product[Categorie],
Regio[Land],
"Aantal", [Aantal orders]
)
De gedocumenteerde aanpassing voegt de betrokken tabellen als filtertabellen toe:
Samenvatting =
SUMMARIZECOLUMNS(
Product[Categorie],
Regio[Land],
Product,
Regio,
"Aantal", [Aantal orders]
)
Pas dit alleen toe wanneer je refreshfout en formule bij dit beschreven scenario passen. De officiële pagina over problemen met refreshscenario's vermeldt ook dat meerdere betrokken berekende tabellen samen in één transactie moeten worden aangepast, waarvoor Power BI Desktop zelf geen batchwijziging biedt.
Veelgemaakte fouten
- Alleen het laatst genoemde object verwijderen. Dat object kan slechts de lus zichtbaar hebben gemaakt; de terugverwijzing kan elders staan.
- Dezelfde kolom onder een andere naam opnieuw maken. Een nieuwe naam verandert de afhankelijkheidsgraaf niet.
- Iedere berekening naar een berekende kolom verplaatsen. Dynamische rapportlogica hoort meestal in een measure.
- ALLEXCEPT zonder unieke sleutel gebruiken. Dan verander je de betekenis van de berekening en blijft de modelkorrel onduidelijk.
- Een relatie op beide richtingen zetten als snelle reparatie. Dat kan nieuwe filterpaden en onduidelijke resultaten maken.
- Een scalarselectie of TOPN-patroon toevoegen.
MAX,SELECTEDVALUEof bijvoorbeeldMAXXover een deterministischeTOPNkan een tabel-met-meerdere-waarden-fout bewust tot één scalar reduceren, maar geen objectcyclus breken.TOPNalleen retourneert nog steeds een tabel. - Sort by Column vergeten. De formule kan één richting tonen terwijl de sorteereigenschap een terugweg toevoegt.
- Alleen een visual testen. Voer in Import ook een volledige refresh uit, omdat berekende kolommen en tabellen dan opnieuw worden geëvalueerd. Test in DirectQuery daarnaast de relevante query's en filtercombinaties, omdat berekende kolommen daar ongematerialiseerd zijn.
Zo voorkom je circulaire afhankelijkheden
Gebruik een lagenmodel: brondata, eventueel Power Query-transformaties, onafhankelijke basiskolommen en basismeters, en pas daarna afgeleide berekeningen. Geef basismeters een herkenbare naam en laat ze nooit afhangen van rapportlabels of afgeleide measures.
Houd dimensies en brugtabellen onafhankelijk van de feitentabellen die zij filteren. Maak sorteerkolommen uit dezelfde bronwaarde als het label. Controleer bij een nieuwe berekende kolom of je een rijwaarde in assen, filters of relaties nodig hebt; gebruik anders liever een measure wanneer de uitkomst met rapportfilters moet veranderen.
Kom je vanuit Excel, lees dan hoe Excel-formules naar DAX vertalen verschilt van celverwijzingen. Voor contextfouten met losse kolommen helpt de single-value-decoder. Alle volgende foutdecoders en modelhandleidingen vind je op de Power BI-hub.
Veelgestelde vragen
- Wat betekent 'A circular dependency was detected' in Power BI?
- Een modelobject verwijst rechtstreeks naar zichzelf, of meerdere modelobjecten zijn direct of indirect zo van elkaar afhankelijk dat de keten terugkomt bij het begin. Daardoor kan Power BI geen geldige rekenvolgorde bepalen. Breek één verwijzing in de lus en leid de betrokken uitkomst af van een stabiele bronkolom, basismeter of onafhankelijke tabel.
- Waarom krijg ik deze fout zonder directe zelfverwijzing?
- De lus kan via meerdere objecten lopen. Kolom A kan kolom B gebruiken, B een measure en die measure via contexttransitie of een andere berekening weer A. Ook berekende tabellen, relaties en Sort by Column kunnen onderdeel van de afhankelijkheidsketen zijn.
- Kunnen twee measures een circular dependency veroorzaken?
- Ja. Als measure A direct of via andere measures measure B gebruikt en B uiteindelijk weer A nodig heeft, ontstaat een cyclus. Laat beide measures vanuit dezelfde onafhankelijke basismeter rekenen en bouw daarna maar één richting op.
- Hoe vind ik welke DAX-objecten van elkaar afhangen?
- Lees eerst de objectketen in de foutmelding en zoek ieder genoemd object in de modelweergave. In DAX Query View kun je, met schrijfrechten en zonder liveverbinding, ook INFO.CALCDEPENDENCY gebruiken om berekeningsafhankelijkheden te bekijken.
- Waarom verschijnt de fout pas bij een tweede berekende kolom?
- Een measure in een berekende kolom activeert contexttransitie en kan daardoor van meer kolommen uit de huidige rij afhankelijk worden dan de formule zichtbaar noemt. Een tweede kolom kan de terugweg in de afhankelijkheidslus toevoegen.
- Lost het verwijderen en opnieuw maken van de kolom de fout op?
- Alleen als je de afhankelijkheidsrichting in de nieuwe formule verandert. Dezelfde verwijzingen opnieuw aanmaken levert dezelfde lus op. Noteer eerst de keten, kies een bronobject en bouw de berekeningen daarna één kant op.
- Kan ik de berekening beter in Power Query maken?
- Ja, vooral in een Import-model wanneer de uitkomst statisch per rij is en alleen bij verversen hoeft te veranderen. Een Power Query-kolom wordt vóór het semantische model gedefinieerd en kan zo een DAX-modelcyclus doorbreken. Bij DirectQuery moet de transformatie naar de bron kunnen worden gevouwen en wordt zij als onderdeel van bronquery's uitgevoerd. Voor interactieve filteruitkomsten blijft een measure meestal de juiste keuze.
Lees ook
Hulp nodig bij jouw situatie?
Kom je er niet uit? Stuur kort wat context, wat je wilt bereiken en waar je vastloopt. Vraag een offerte aan als je wilt dat ik het voor je oplos.
w.bouwmeester@bouwmeesterconsultancy.nl · +31 6 28963636