diff --git a/spec/value_ref/value_ref_partial_session.spec.ts b/spec/value_ref/value_ref_partial_session.spec.ts
new file mode 100644
index 0000000000000000000000000000000000000000..c974bb714f2b91b04d6501bd07d467a34063bad9
--- /dev/null
+++ b/spec/value_ref/value_ref_partial_session.spec.ts
@@ -0,0 +1,110 @@
+import { ExtensionStrategy, ParamValueMode } from "../../src/index";
+import { Nub } from "../../src/nub";
+import { PabChute, PabChuteParams } from "../../src/pab/pab_chute";
+import { PabNombre, PabNombreParams } from "../../src/pab/pab_nombre";
+import { Session } from "../../src/session";
+
+function saveAndReload(nubToSave: Nub): Nub {
+        // partial saving
+        const options: any = {};
+        options[nubToSave.uid] = true; // save only this Nub
+        const json = Session.getInstance().serialise(options);
+        // reloading
+        Session.getInstance().clear();
+        Session.getInstance().unserialise(json);
+        const reloadedNub = Session.getInstance().findNubByUid(nubToSave.uid);
+        return reloadedNub;
+}
+
+describe("partial session saving/reloading : ", () => {
+
+    it("link to single param", () => {
+        // init scenario
+        Session.getInstance().clear();
+        const pabChute = new PabChute(new PabChuteParams(3, 0.7, 2.3));
+        Session.getInstance().registerNub(pabChute);
+        const pabNombre = new PabNombre(new PabNombreParams(7, 20, 0.35));
+        Session.getInstance().registerNub(pabNombre);
+        pabChute.calculatedParam = pabChute.prms.Z2;
+        pabNombre.prms.DHT.defineReference(pabChute, "DH");
+
+        const loadedPabNombre = saveAndReload(pabNombre);
+        // check values
+        expect(loadedPabNombre.getParameter("DHT").valueMode).toEqual(ParamValueMode.SINGLE);
+        expect(loadedPabNombre.getParameter("DHT").singleValue).toEqual(2.3);
+    });
+
+    it("link to minmax param", () => {
+        // init scenario
+        Session.getInstance().clear();
+        const pabChute = new PabChute(new PabChuteParams(3, 0.7, 2.3));
+        Session.getInstance().registerNub(pabChute);
+        const pabNombre = new PabNombre(new PabNombreParams(7, 20, 0.35));
+        Session.getInstance().registerNub(pabNombre);
+        pabChute.calculatedParam = pabChute.prms.Z2;
+        pabChute.prms.DH.setValues(2, 2.5, 0.1);
+        pabChute.prms.DH.extensionStrategy = ExtensionStrategy.REPEAT_LAST;
+        pabNombre.prms.DHT.defineReference(pabChute, "DH");
+
+        const loadedPabNombre = saveAndReload(pabNombre);
+        // check values
+        expect(loadedPabNombre.getParameter("DHT").valueMode).toEqual(ParamValueMode.MINMAX);
+        expect(loadedPabNombre.getParameter("DHT").min).toEqual(2);
+        expect(loadedPabNombre.getParameter("DHT").max).toEqual(2.5);
+        expect(loadedPabNombre.getParameter("DHT").step).toEqual(0.1);
+        expect(loadedPabNombre.getParameter("DHT").extensionStrategy).toEqual(ExtensionStrategy.REPEAT_LAST);
+    });
+
+    it("link to list param", () => {
+        // init scenario
+        Session.getInstance().clear();
+        const pabChute = new PabChute(new PabChuteParams(3, 0.7, 2.3));
+        Session.getInstance().registerNub(pabChute);
+        const pabNombre = new PabNombre(new PabNombreParams(7, 20, 0.35));
+        Session.getInstance().registerNub(pabNombre);
+        pabChute.calculatedParam = pabChute.prms.Z2;
+        pabChute.prms.DH.setValues([ 3.1, 3.2, 3.3 ]);
+        pabChute.prms.DH.extensionStrategy = ExtensionStrategy.REPEAT_LAST;
+        pabNombre.prms.DHT.defineReference(pabChute, "DH");
+
+        const loadedPabNombre = saveAndReload(pabNombre);
+        // check values
+        expect(loadedPabNombre.getParameter("DHT").valueMode).toEqual(ParamValueMode.LISTE);
+        expect(loadedPabNombre.getParameter("DHT").valueList).toEqual([ 3.1, 3.2, 3.3 ]);
+        expect(loadedPabNombre.getParameter("DHT").extensionStrategy).toEqual(ExtensionStrategy.REPEAT_LAST);
+    });
+
+    it("link to calculated param", () => {
+        // init scenario
+        Session.getInstance().clear();
+        const pabChute = new PabChute(new PabChuteParams(3, 0.6, 2));
+        Session.getInstance().registerNub(pabChute);
+        const pabNombre = new PabNombre(new PabNombreParams(7, 20, 0.35));
+        Session.getInstance().registerNub(pabNombre);
+        pabChute.calculatedParam = pabChute.prms.DH;
+        pabNombre.prms.DHT.defineReference(pabChute, "DH");
+
+        const loadedPabNombre = saveAndReload(pabNombre);
+        // check values
+        expect(loadedPabNombre.getParameter("DHT").valueMode).toEqual(ParamValueMode.SINGLE);
+        expect(loadedPabNombre.getParameter("DHT").singleValue).toEqual(2.4); // 3 - 0.6
+    });
+
+    it("link to calculated variated param", () => {
+        // init scenario
+        Session.getInstance().clear();
+        const pabChute = new PabChute(new PabChuteParams(3, 0.6, 2));
+        Session.getInstance().registerNub(pabChute);
+        const pabNombre = new PabNombre(new PabNombreParams(7, 20, 0.35));
+        Session.getInstance().registerNub(pabNombre);
+        pabChute.calculatedParam = pabChute.prms.DH;
+        pabChute.prms.Z1.setValues(2.9, 3.1, 0.1);
+        pabNombre.prms.DHT.defineReference(pabChute, "DH");
+
+        const loadedPabNombre = saveAndReload(pabNombre);
+        // check values
+        expect(loadedPabNombre.getParameter("DHT").valueMode).toEqual(ParamValueMode.LISTE);
+        expect(loadedPabNombre.getParameter("DHT").valueList).toEqual([ 2.3, 2.4, 2.5 ]); // [ 2.9, 3.0, 3.1 ] - 0.6
+    });
+
+});
diff --git a/src/nub.ts b/src/nub.ts
index e4809e58135d1c0b994b75d0e09dc9420369bfd4..36dbbb0e637ca77a0d4b2b8b7cd31b4e4726b483 100644
--- a/src/nub.ts
+++ b/src/nub.ts
@@ -861,8 +861,11 @@ export abstract class Nub extends ComputeNode implements IObservable {
     /**
      * Returns an object representation of the Nub's current state
      * @param extra extra key-value pairs, for ex. calculator title in GUI
+     * @param nubUidsInSession UIDs of Nubs that will be saved in session along with this one;
+     *                         useful to determine if linked parameters must be kept as links
+     *                         or have their value copied (if target is not in UIDs list)
      */
-    public objectRepresentation(extra?: object) {
+    public objectRepresentation(extra?: object, nubUidsInSession?: string[]): object {
         let ret: any = {
             uid: this.uid,
             props: Session.invertEnumKeysAndValuesInProperties(this.properties.props),
@@ -877,13 +880,13 @@ export abstract class Nub extends ComputeNode implements IObservable {
         const localParametersIterator =  new ParamsEquationArrayIterator([this._prms]);
         for (const p of localParametersIterator) {
             if (p.visible) {
-                ret.parameters.push(p.objectRepresentation());
+                ret.parameters.push(p.objectRepresentation(nubUidsInSession));
             }
         }
 
         // iterate over children Nubs
         for (const child of this._children) {
-            ret.children.push(child.objectRepresentation());
+            ret.children.push(child.objectRepresentation(undefined, nubUidsInSession));
         }
 
         return ret;
diff --git a/src/param/param-definition.ts b/src/param/param-definition.ts
index fd7362becbbeeb72e68560a5726c596a8fd8710b..53ca53572379548517c645b980e6498af6c64b0a 100644
--- a/src/param/param-definition.ts
+++ b/src/param/param-definition.ts
@@ -742,8 +742,11 @@ export class ParamDefinition implements INamedIterableValues, IObservable {
 
     /**
      * Returns an object representation of the Parameter's current state
+     * @param nubUidsInSession UIDs of Nubs that will be saved in session along with this one;
+     *                         useful to determine if linked parameters must be kept as links
+     *                         or have their value copied (if target is not in UIDs list)
      */
-    public objectRepresentation(): { symbol: string, mode: string } {
+    public objectRepresentation(nubUidsInSession?: string[]): { symbol: string, mode: string } {
         // parameter representation
         const paramRep: any = {
             symbol: this.symbol,
@@ -768,8 +771,31 @@ export class ParamDefinition implements INamedIterableValues, IObservable {
                 break;
 
             case ParamValueMode.LINK:
-                paramRep.targetNub = this._referencedValue.nub.uid;
-                paramRep.targetParam = this._referencedValue.symbol;
+                if (nubUidsInSession !== undefined && nubUidsInSession.includes(this._referencedValue.nub.uid)) {
+                    // target Nub is available in session, link won't get broken
+                    paramRep.targetNub = this._referencedValue.nub.uid;
+                    paramRep.targetParam = this._referencedValue.symbol;
+                } else {
+                    // target Nub will be lost, copy value(s) to keep consistency
+                    const targetPV = this._referencedValue.getParamValues(true);
+                    paramRep.mode = ParamValueMode[targetPV.valueMode];
+                    switch (targetPV.valueMode) {
+                        case ParamValueMode.SINGLE:
+                            paramRep.value = targetPV.singleValue;
+                            break;
+                        case ParamValueMode.MINMAX:
+                            paramRep.min = targetPV.min;
+                            paramRep.max = targetPV.max;
+                            paramRep.step = targetPV.step;
+                            paramRep.extensionStrategy = targetPV.extensionStrategy;
+                            break;
+                        case ParamValueMode.LISTE:
+                            paramRep.values = targetPV.valueList;
+                            paramRep.extensionStrategy = targetPV.extensionStrategy;
+                            break;
+                        // should never be in LINK or CALC mode (see LinkedValue methods)
+                    }
+                }
                 break;
         }
         return paramRep;
diff --git a/src/session.ts b/src/session.ts
index 745bc6c54e7e9a1808d361baa1df2c1be5eb1570..f340f7433a394b694ede5a63758bb90926a30fc4 100644
--- a/src/session.ts
+++ b/src/session.ts
@@ -155,9 +155,9 @@ export class Session {
         }
         for (const n of this._nubs) {
             if (ids.length === 0) {
-                sess.push(n.objectRepresentation());
+                sess.push(n.objectRepresentation(undefined, ids));
             } else if (ids.includes(n.uid)) {
-                sess.push(n.objectRepresentation(options[n.uid]));
+                sess.push(n.objectRepresentation(options[n.uid], ids));
             }
         }
         return JSON.stringify({