diff --git a/app/but/jury_but.py b/app/but/jury_but.py
index 9d56cb97b..86a5e4a9a 100644
--- a/app/but/jury_but.py
+++ b/app/but/jury_but.py
@@ -93,7 +93,7 @@ from app.scodoc import sco_cache
 from app.scodoc import sco_codes_parcours as sco_codes
 from app.scodoc.sco_codes_parcours import CODES_UE_VALIDES, RED, UE_STANDARD
 from app.scodoc import sco_utils as scu
-from app.scodoc.sco_exceptions import ScoException, ScoValueError
+from app.scodoc.sco_exceptions import ScoNoReferentielCompetences, ScoValueError
 
 
 class NoRCUEError(ScoValueError):
@@ -205,6 +205,8 @@ class DecisionsProposeesAnnee(DecisionsProposees):
         formsemestre: FormSemestre,
     ):
         assert formsemestre.formation.is_apc()
+        if formsemestre.formation.referentiel_competence is None:
+            raise ScoNoReferentielCompetences(formation=formsemestre.formation)
         super().__init__(etud=etud)
         self.formsemestre = formsemestre
         "le formsemestre utilisé pour construire ce deca"
@@ -1148,7 +1150,7 @@ class BUTCursusEtud:  # WIP TODO
 
     def __init__(self, formsemestre: FormSemestre, etud: Identite):
         if formsemestre.formation.referentiel_competence is None:
-            raise ScoException("BUTCursusEtud: pas de référentiel de compétences")
+            raise ScoNoReferentielCompetences(formation=formsemestre.formation)
         assert len(etud.formsemestre_inscriptions) > 0
         self.formsemestre = formsemestre
         self.etud = etud
diff --git a/app/but/jury_but_recap.py b/app/but/jury_but_recap.py
index ecaf1e116..386579575 100644
--- a/app/but/jury_but_recap.py
+++ b/app/but/jury_but_recap.py
@@ -32,7 +32,7 @@ from app.scodoc.sco_codes_parcours import (
 from app.scodoc import sco_formsemestre_status
 from app.scodoc import sco_pvjury
 from app.scodoc import sco_utils as scu
-from app.scodoc.sco_exceptions import ScoValueError
+from app.scodoc.sco_exceptions import ScoNoReferentielCompetences
 
 
 def formsemestre_saisie_jury_but(
@@ -63,14 +63,7 @@ def formsemestre_saisie_jury_but(
     #    raise ScoValueError("Cette page ne fonctionne que sur les semestres pairs")
 
     if formsemestre2.formation.referentiel_competence is None:
-        raise ScoValueError(
-            """
-        <p>Pas de référentiel de compétences associé à la formation !</p>
-        <p>Pour associer un référentiel, passer par le menu <b>Semestre /
-        Voir la formation... </b> et suivre le lien <em>"associer à un référentiel
-        de compétences"</em>
-        """
-        )
+        raise ScoNoReferentielCompetences(formation=formsemestre2.formation)
 
     rows, titles, column_ids, jury_stats = get_jury_but_table(
         formsemestre2, read_only=read_only, mode=mode
diff --git a/app/models/but_refcomp.py b/app/models/but_refcomp.py
index c8487ecf5..b1617212b 100644
--- a/app/models/but_refcomp.py
+++ b/app/models/but_refcomp.py
@@ -14,7 +14,7 @@ import sqlalchemy
 from app import db
 
 from app.scodoc.sco_utils import ModuleType
-from app.scodoc.sco_exceptions import ScoValueError
+from app.scodoc.sco_exceptions import ScoNoReferentielCompetences
 
 
 # from https://stackoverflow.com/questions/2537471/method-of-iterating-over-sqlalchemy-models-defined-columns
@@ -322,9 +322,8 @@ class ApcNiveau(db.Model, XMLModel):
         if annee not in {1, 2, 3}:
             raise ValueError("annee invalide pour un parcours BUT")
         if referentiel_competence is None:
-            raise ScoValueError(
-                "Pas de référentiel de compétences associé à la formation !"
-            )
+            raise ScoNoReferentielCompetences()
+
         annee_formation = f"BUT{annee}"
         if parcour is None:
             return ApcNiveau.query.filter(
diff --git a/app/scodoc/sco_exceptions.py b/app/scodoc/sco_exceptions.py
index 226c1c9f7..7f4a67904 100644
--- a/app/scodoc/sco_exceptions.py
+++ b/app/scodoc/sco_exceptions.py
@@ -40,8 +40,9 @@ class InvalidNoteValue(ScoException):
     pass
 
 
-# Exception qui stoque dest_url
 class ScoValueError(ScoException):
+    "Exception avec page d'erreur utilisateur, et qui stoque dest_url"
+
     def __init__(self, msg, dest_url=None):
         super().__init__(msg)
         self.dest_url = dest_url
@@ -74,7 +75,7 @@ class ScoFormatError(ScoValueError):
 
 class ScoInvalidParamError(ScoValueError):
     """Paramètres requete invalides.
-    A utilisée lorsqu'une route est appelée avec des paramètres invalides
+    Utilisée lorsqu'une route est appelée avec des paramètres invalides
     (id strings, ...)
     """
 
@@ -157,6 +158,23 @@ class ScoInvalidIdType(ScoValueError):
         super().__init__(msg)
 
 
+class ScoNoReferentielCompetences(ScoValueError):
+    """Formation APC (BUT) non associée à référentiel de compétences"""
+
+    def __init__(self, msg: str = "", formation: "Formation" = None):
+        formation_title = (
+            f"{formation.title} version {formation.version}" if formation else ""
+        )
+        msg = f"""
+        <p>Pas de référentiel de compétences associé à la formation {formation_title}!
+        </p>
+        <p>Pour associer un référentiel, passer par le menu <b>Semestre /
+        Voir la formation... </b> et suivre le lien <em>"associer à un référentiel
+        de compétences"</em>
+        """
+        super().__init__(msg)
+
+
 class ScoGenError(ScoException):
     "exception avec affichage d'une page explicative ad-hoc"
 
diff --git a/app/scodoc/sco_liste_notes.py b/app/scodoc/sco_liste_notes.py
index e2a3890e7..2a63078b4 100644
--- a/app/scodoc/sco_liste_notes.py
+++ b/app/scodoc/sco_liste_notes.py
@@ -76,7 +76,7 @@ def do_evaluation_listenotes(
     else:
         raise ValueError("missing argument: evaluation or module")
     if not evals:
-        return "<p>Aucune évaluation !</p>", f"ScoDoc"
+        return "<p>Aucune évaluation !</p>", "ScoDoc"
 
     E = evals[0]  # il y a au moins une evaluation
     modimpl = ModuleImpl.query.get(E["moduleimpl_id"])
@@ -244,7 +244,6 @@ def _make_table_notes(
     E = evals[0]
     moduleimpl_id = E["moduleimpl_id"]
     modimpl = ModuleImpl.query.get_or_404(moduleimpl_id)
-    modimpl_o = modimpl.to_dict()  # TODO temporaire - à refactorer
     module: Module = modimpl.module
     formsemestre: FormSemestre = modimpl.formsemestre
     is_apc = module.formation.get_parcours().APC_SAE
diff --git a/app/scodoc/sco_saisie_notes.py b/app/scodoc/sco_saisie_notes.py
index d00a2dcba..3b980df04 100644
--- a/app/scodoc/sco_saisie_notes.py
+++ b/app/scodoc/sco_saisie_notes.py
@@ -426,16 +426,16 @@ def do_evaluation_set_missing(
 
 def evaluation_suppress_alln(evaluation_id, dialog_confirmed=False):
     "suppress all notes in this eval"
-    E = sco_evaluation_db.do_evaluation_list({"evaluation_id": evaluation_id})[0]
+    evaluation = Evaluation.query.get_or_404(evaluation_id)
 
     if sco_permissions_check.can_edit_notes(
-        current_user, E["moduleimpl_id"], allow_ens=False
+        current_user, evaluation.moduleimpl_id, allow_ens=False
     ):
         # On a le droit de modifier toutes les notes
         # recupere les etuds ayant une note
         notes_db = sco_evaluation_db.do_evaluation_get_all_notes(evaluation_id)
     elif sco_permissions_check.can_edit_notes(
-        current_user, E["moduleimpl_id"], allow_ens=True
+        current_user, evaluation.moduleimpl_id, allow_ens=True
     ):
         # Enseignant associé au module: ne peut supprimer que les notes qu'il a saisi
         notes_db = sco_evaluation_db.do_evaluation_get_all_notes(
@@ -449,7 +449,7 @@ def evaluation_suppress_alln(evaluation_id, dialog_confirmed=False):
     status_url = url_for(
         "notes.moduleimpl_status",
         scodoc_dept=g.scodoc_dept,
-        moduleimpl_id=E["moduleimpl_id"],
+        moduleimpl_id=evaluation.moduleimpl_id,
     )
 
     if not dialog_confirmed:
@@ -495,13 +495,12 @@ def evaluation_suppress_alln(evaluation_id, dialog_confirmed=False):
         """
     ]
     # news
-    modimpl = ModuleImpl.query.get(E["moduleimpl_id"])
     ScolarNews.add(
         typ=ScolarNews.NEWS_NOTE,
-        obj=modimpl.id,
+        obj=evaluation.moduleimpl.id,
         text=f"""Suppression des notes d'une évaluation dans
         <a class="stdlink" href="{status_url}"
-        >{modimpl.module.titre or 'module sans titre'}</a>
+        >{evaluation.moduleimpl.module.titre or 'module sans titre'}</a>
         """,
         url=status_url,
     )