diff --git a/src/app/components/param-field-line/param-field-line.component.html b/src/app/components/param-field-line/param-field-line.component.html
index 07d31672d74fa61e868a16c2b971b91949b4a708..1143ac972b73bc22e3b3d8dad26e806443f92ff9 100644
--- a/src/app/components/param-field-line/param-field-line.component.html
+++ b/src/app/components/param-field-line/param-field-line.component.html
@@ -38,7 +38,7 @@
             </mat-button-toggle>
 
             <mat-button-toggle class="radio_cal" value="radio_cal" *ngIf="hasRadioCal()" (click)="onRadioClick('cal')"
-                [checked]="isRadioCalChecked">
+                [checked]="isRadioCalChecked" [disabled]="isRadioCalDisabled" [title]="radioCalTitle">
                 <span fxHide.xxs>{{ uitextParamCalculer }}</span>
                 <span fxHide.gt-xxs>C</span>
             </mat-button-toggle>
diff --git a/src/app/components/param-field-line/param-field-line.component.ts b/src/app/components/param-field-line/param-field-line.component.ts
index 0fd0a4eb2688a3bf127f9da9e0a97d2cfb739399..22b7a92ad09a49c78ac0f54cb6ee01e44bc06fbc 100644
--- a/src/app/components/param-field-line/param-field-line.component.ts
+++ b/src/app/components/param-field-line/param-field-line.component.ts
@@ -199,6 +199,30 @@ export class ParamFieldLineComponent implements OnChanges {
         return ret;
     }
 
+    /**
+     * Returns true if setting this parameter to Calc mode leads to a links loop
+     */
+    public get isRadioCalDisabled(): boolean {
+        // find all Nubs that have to be calculated for this one to run
+        const nub = this.param.paramDefinition.originNub;
+        const requiredNubs = nub.getRequiredNubsDeep();
+        // if one of those Nubs depends on the parameter we're about to set
+        // to Calc mode, then we shouldn't do so
+        for (const r of requiredNubs) {
+            if (r.dependsOnParameter(this.param.paramDefinition)) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    public get radioCalTitle(): string {
+        if (this.isRadioCalDisabled) {
+            return this.intlService.localizeText("INFO_PARAMFIELD_CANNOT_CALC_LINKS_LOOP");
+        }
+        return "";
+    }
+
     public onRadioClick(option: string) {
         const oldValue = this.param.valueMode;
         switch (option) {
diff --git a/src/locale/messages.en.json b/src/locale/messages.en.json
index cecb243f905108fd16b52005831bdf72d75ab8d6..e5991f549c18967a2283d73480ab147ec033b61f 100644
--- a/src/locale/messages.en.json
+++ b/src/locale/messages.en.json
@@ -454,6 +454,7 @@
     "INFO_PARAMFIELD_BOUNDARY_CONDITIONS": "Boundary conditions",
     "INFO_PARAMFIELD_CALCULATED": "Calculated",
     "INFO_PARAMFIELD_CALCULATION_FAILED": "Calculation failed",
+    "INFO_PARAMFIELD_CANNOT_CALC_LINKS_LOOP": "This parameter cannot be calculated (links loop)",
     "INFO_PARAMFIELD_CHART_SELECT_X_AXIS": "Variable for X axis",
     "INFO_PARAMFIELD_CHART_SELECT_Y_AXIS": "Variable for Y axis",
     "INFO_PARAMFIELD_CHART_TYPE_HISTOGRAM": "Histogram",
diff --git a/src/locale/messages.fr.json b/src/locale/messages.fr.json
index df635cb2603c7ddf07d220e56a6ea03dde0c3518..cae8286ea260938fc0a3f1f341727ae11438c7b6 100644
--- a/src/locale/messages.fr.json
+++ b/src/locale/messages.fr.json
@@ -455,6 +455,7 @@
     "INFO_PARAMFIELD_BOUNDARY_CONDITIONS": "Conditions aux limites",
     "INFO_PARAMFIELD_CALCULATED": "Calculé",
     "INFO_PARAMFIELD_CALCULATION_FAILED": "Échec du calcul",
+    "INFO_PARAMFIELD_CANNOT_CALC_LINKS_LOOP": "Ce paramètre ne peut être calculé (boucle dans les liens)",
     "INFO_PARAMFIELD_CHART_SELECT_X_AXIS": "Variable en abscisse",
     "INFO_PARAMFIELD_CHART_SELECT_Y_AXIS": "Variable en ordonnée",
     "INFO_PARAMFIELD_CHART_TYPE_HISTOGRAM": "Histogramme",