diff --git a/app/formations/edit_module.py b/app/formations/edit_module.py
index b8b389d9ae26cc9ff2c4d4c1790731cd81d84b23..34673579dae425062cc584b3c91483cd77f497f9 100644
--- a/app/formations/edit_module.py
+++ b/app/formations/edit_module.py
@@ -720,14 +720,21 @@ def module_edit(
                 raise ScoValueError(
                     "Module utilisé: il ne peut pas être changé de semestre !"
                 )
-        # En APC, force le semestre égal à celui de l'UE
+        if not tf[2].get("code"):
+            raise ScoValueError("Le code du module doit être spécifié.")
+
         if is_apc:
+            # En APC, force le semestre égal à celui de l'UE
             selected_ue = db.session.get(UniteEns, tf[2]["ue_id"])
             if selected_ue is None:
                 raise ValueError("UE invalide")
             tf[2]["semestre_id"] = selected_ue.semestre_idx
-        if not tf[2].get("code"):
-            raise ScoValueError("Le code du module doit être spécifié.")
+            # Et vérifie que les AC sont bien dans ce ref. comp.
+            if "app_critiques" in tf[2]:
+                tf[2]["app_critiques"] = Module.convert_app_critiques(
+                    tf[2]["app_critiques"], formation.referentiel_competence
+                )
+
         # Check unicité code module dans la formation
         # ??? TODO
         #
@@ -741,12 +748,6 @@ def module_edit(
                 db.session.get(ApcParcours, int(parcour_id_str))
                 for parcour_id_str in form_parcours
             ]
-    # Modifie les AC
-    if "app_critiques" in tf[2]:
-        module.app_critiques = [
-            db.session.get(ApcAppCritique, int(ac_id_str))
-            for ac_id_str in tf[2]["app_critiques"]
-        ]
     db.session.add(module)
     db.session.commit()
     module.formation.invalidate_cached_sems()
diff --git a/app/models/modules.py b/app/models/modules.py
index 37cded355fe1ef74d7e7069f79f3f2a1014df620..339b59d5ad3deba80742e845461cb94e582fd459 100644
--- a/app/models/modules.py
+++ b/app/models/modules.py
@@ -8,6 +8,7 @@ from app import db, log
 from app import models
 from app.models import APO_CODE_STR_LEN
 from app.models.but_refcomp import (
+    ApcAppCritique,
     ApcParcours,
     ApcReferentielCompetences,
     app_critiques_modules,
@@ -109,10 +110,31 @@ class Module(models.ScoDocModel):
             if hasattr(cls, key) and not isinstance(getattr(cls, key, None), property):
                 if key in fs_empty_stored_as_nulls and value == "":
                     value = None
-            args_dict[key] = value
+                args_dict[key] = value
+            if key == "app_critiques":  # peut être liste d'ApcAppCritique ou d'ids
+                args_dict[key] = cls.convert_app_critiques(value)
 
         return args_dict
 
+    @staticmethod
+    def convert_app_critiques(
+        app_crits: list, ref_comp: ApcReferentielCompetences | None = None
+    ) -> list[ApcAppCritique]:
+        """ """
+        res = []
+        for x in app_crits:
+            app_crit = (
+                x
+                if isinstance(x, ApcAppCritique)
+                else db.session.get(ApcAppCritique, x)
+            )
+            if app_crit is None:
+                raise ScoValueError("app_critiques invalid")
+            if ref_comp and app_crit.niveau.competence.referentiel_id != ref_comp.id:
+                raise ScoValueError("app_critique hors référentiel !")
+            res.append(app_crit)
+        return res
+
     @classmethod
     def filter_model_attributes(cls, args: dict, excluded: set[str] = None) -> dict:
         """Returns a copy of dict with only the keys belonging to the Model and not in excluded.