diff --git a/src/kernel_services/ast_data/annotations.ml b/src/kernel_services/ast_data/annotations.ml
index 8869fe97088901d6ae11313b3bb9cb474203aec4..56739c79dd7706fde593cbef832fe22275d1d18c 100644
--- a/src/kernel_services/ast_data/annotations.ml
+++ b/src/kernel_services/ast_data/annotations.ml
@@ -365,14 +365,7 @@ let code_annot_emitter ?filter stmt =
   try
     let tbl = Code_annots.find stmt in
     let filter e l acc =
-      let e =
-        try Emitter.Usable_emitter.get e
-        with Not_found ->
-          (* in some cases, e.g. when loading a state with a different set
-             of plugins loaded, the original emitter might not be available,
-             leading to discarding annotations. Let the kernel adopt them. *)
-          Emitter.orphan
-      in
+      let e = Emitter.Usable_emitter.get e in
       match filter with
       | None -> List.map (fun a -> a, e) l @ acc
       | Some f ->
diff --git a/src/kernel_services/plugin_entry_points/emitter.ml b/src/kernel_services/plugin_entry_points/emitter.ml
index d44861ba06cd48b63905c295e0fa67284b34b33c..9f5ada97cc5e2a407f0dd6ea0b06003a43b9a9d9 100644
--- a/src/kernel_services/plugin_entry_points/emitter.ml
+++ b/src/kernel_services/plugin_entry_points/emitter.ml
@@ -23,10 +23,6 @@
 (* Modules [Hashtbl] and [Kernel] are not usable here. Thus use above modules
    instead. *)
 
-(**************************************************************************)
-(** {2 Datatype} *)
-(**************************************************************************)
-
 type kind = Property_status | Alarm | Code_annot | Funspec | Global_annot
 
 type emitter =
@@ -35,6 +31,59 @@ type emitter =
     tuning_parameters: Typed_parameter.t list;
     correctness_parameters: Typed_parameter.t list }
 
+(**************************************************************************)
+(** {2 Implementation for Plug-in Developers} *)
+(**************************************************************************)
+
+let names: unit Datatype.String.Hashtbl.t = Datatype.String.Hashtbl.create 7
+
+let create name kinds ~correctness ~tuning =
+  if Datatype.String.Hashtbl.mem names name then
+    Kernel.fatal "emitter %s already exists with the same parameters" name;
+  let e =
+    { name = name;
+      kinds = kinds;
+      correctness_parameters = correctness;
+      tuning_parameters = tuning }
+  in
+  Datatype.String.Hashtbl.add names name ();
+  e
+
+let dummy = create "dummy" [] ~correctness:[] ~tuning:[]
+
+let get_name e = e.name
+
+let correctness_parameters e =
+  List.map (fun p -> p.Typed_parameter.name) e.correctness_parameters
+
+let tuning_parameters e =
+  List.map (fun p -> p.Typed_parameter.name) e.tuning_parameters
+
+let end_user =
+  create
+    "End-User"
+    [ Property_status; Code_annot; Funspec; Global_annot ]
+    ~correctness:[]
+    ~tuning:[]
+
+let kernel =
+  create
+    "Frama-C kernel"
+    [ Property_status; Funspec ]
+    ~correctness:[]
+    ~tuning:[]
+
+let orphan =
+  create
+    "Orphan"
+    [ Code_annot; Funspec; Global_annot ]
+    ~correctness:[]
+    ~tuning:[]
+
+(**************************************************************************)
+(** {2 Datatype} *)
+(**************************************************************************)
+
 module D =
   Datatype.Make_with_collections
     (struct
@@ -106,7 +155,7 @@ module Usable_emitter = struct
         let mem_project = Datatype.never_any_project
       end)
 
-  let get e =
+  let unsafe_get e =
     let get_params map =
       Datatype.String.Map.fold
         (fun s _ acc -> Typed_parameter.get s :: acc)
@@ -118,6 +167,13 @@ module Usable_emitter = struct
       correctness_parameters = get_params e.correctness_values;
       tuning_parameters = get_params e.tuning_values }
 
+  (* In some cases, e.g. when loading a state with a different set
+     of plugins loaded, the original emitter might not be available,
+     leading to discarding annotations. Let the kernel adopt them. *)
+  let get e =
+    try unsafe_get e
+    with Not_found -> orphan
+
   let get_name e = e.u_name
   let get_unique_name e = Format.asprintf "%a" pretty e
 
@@ -134,55 +190,6 @@ module Usable_emitter = struct
 
 end
 
-(**************************************************************************)
-(** {2 Implementation for Plug-in Developers} *)
-(**************************************************************************)
-
-let names: unit Datatype.String.Hashtbl.t = Datatype.String.Hashtbl.create 7
-
-let create name kinds ~correctness ~tuning =
-  if Datatype.String.Hashtbl.mem names name then
-    Kernel.fatal "emitter %s already exists with the same parameters" name;
-  let e =
-    { name = name;
-      kinds = kinds;
-      correctness_parameters = correctness;
-      tuning_parameters = tuning }
-  in
-  Datatype.String.Hashtbl.add names name ();
-  e
-
-let dummy = create "dummy" [] ~correctness:[] ~tuning:[]
-
-let get_name e = e.name
-
-let correctness_parameters e =
-  List.map (fun p -> p.Typed_parameter.name) e.correctness_parameters
-
-let tuning_parameters e =
-  List.map (fun p -> p.Typed_parameter.name) e.tuning_parameters
-
-let end_user =
-  create
-    "End-User"
-    [ Property_status; Code_annot; Funspec; Global_annot ]
-    ~correctness:[]
-    ~tuning:[]
-
-let kernel =
-  create
-    "Frama-C kernel"
-    [ Property_status; Funspec ]
-    ~correctness:[]
-    ~tuning:[]
-
-let orphan =
-  create
-    "Orphan"
-    [ Code_annot; Funspec; Global_annot ]
-    ~correctness:[]
-    ~tuning:[]
-
 (**************************************************************************)
 (** {2 State of all known emitters} *)
 (**************************************************************************)
diff --git a/tests/misc/oracle/orphan_emitter.res.oracle b/tests/misc/oracle/orphan_emitter.res.oracle
new file mode 100644
index 0000000000000000000000000000000000000000..b4a4e9e9636b1ef49df2c0fd7a6aaf94a196a565
--- /dev/null
+++ b/tests/misc/oracle/orphan_emitter.res.oracle
@@ -0,0 +1,2 @@
+[kernel] Warning: emitter emitter1: correctness parameter -orphan does not exist anymore. Ignored.
+[kernel] Warning: 11 states in saved file ignored. They are invalid in this Frama-C configuration.
diff --git a/tests/misc/oracle/orphan_emitter_sav.err b/tests/misc/oracle/orphan_emitter_sav.err
new file mode 100644
index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
diff --git a/tests/misc/oracle/orphan_emitter_sav.res b/tests/misc/oracle/orphan_emitter_sav.res
new file mode 100644
index 0000000000000000000000000000000000000000..8a5aa9b933fce678411ffde32a3361b0f2f4ce08
--- /dev/null
+++ b/tests/misc/oracle/orphan_emitter_sav.res
@@ -0,0 +1 @@
+[kernel] Parsing orphan_emitter.i (no preprocessing)
diff --git a/tests/misc/orphan_emitter.i b/tests/misc/orphan_emitter.i
new file mode 100644
index 0000000000000000000000000000000000000000..43b7d53e648cbfb3063b93f83cae64e896ac15ab
--- /dev/null
+++ b/tests/misc/orphan_emitter.i
@@ -0,0 +1,12 @@
+/* run.config
+ PLUGIN: @EVA_PLUGINS@
+ MODULE: @PTEST_NAME@
+   EXECNOW: BIN @PTEST_NAME@.sav LOG @PTEST_NAME@_sav.res LOG @PTEST_NAME@_sav.err @frama-c@ @PTEST_FILE@ -save @PTEST_NAME@.sav > @PTEST_NAME@_sav.res 2> @PTEST_NAME@_sav.err
+ MODULE:
+ COMMENT: the CMD line below omits @PTEST_FILE@ on purpose (due to -load)
+ CMD: @frama-c@ @PTEST_OPTIONS@
+   OPT: -load %{dep:@PTEST_NAME@.sav} -eva -eva-verbose 0
+*/
+int main() {
+  return 0;
+}
diff --git a/tests/misc/orphan_emitter.ml b/tests/misc/orphan_emitter.ml
new file mode 100644
index 0000000000000000000000000000000000000000..573894ba52e7d833dad60df9e527c724769e1e63
--- /dev/null
+++ b/tests/misc/orphan_emitter.ml
@@ -0,0 +1,21 @@
+module P =
+  Plugin.Register
+    (struct
+      let name = "Orphan"
+      let shortname = "orphan"
+      let help = ""
+     end)
+
+module S =
+  P.True(struct let option_name = "-orphan" let help = "" end)
+
+let emitter1 =
+  Emitter.create "emitter1" [ Emitter.Code_annot ]
+    ~correctness:[ S.parameter ] ~tuning:[]
+
+let main () =
+  let kf = Globals.Functions.find_by_name "main" in
+  let stmt = Kernel_function.find_first_stmt kf in
+  Annotations.add_assert emitter1 stmt Logic_const.ptrue
+
+let () = Db.Main.extend main