diff --git a/src/Entity/ReactionRuleConfig.php b/src/Entity/ReactionRuleConfig.php
index ce0690e1..14396b82 100644
--- a/src/Entity/ReactionRuleConfig.php
+++ b/src/Entity/ReactionRuleConfig.php
@@ -283,6 +283,11 @@ class ReactionRuleConfig extends ConfigEntityBase implements RulesUiComponentPro
     if (($id = array_search($event_name, $indexed_event_names)) !== FALSE) {
       unset($this->events[$id]);
     }
+    // Use array_values() to re-index $this->events to ensure that this data
+    // structure always has numerical keys that are ordered sequentially,
+    // starting with 0. Removing an event might have left a gap in this
+    // sequence, which would affect how the configuration was stored.
+    $this->events = array_values($this->events);
     return $this;
   }
 
diff --git a/tests/src/Unit/Entity/ReactionRuleConfigTest.php b/tests/src/Unit/Entity/ReactionRuleConfigTest.php
index 579b919b..b845f675 100644
--- a/tests/src/Unit/Entity/ReactionRuleConfigTest.php
+++ b/tests/src/Unit/Entity/ReactionRuleConfigTest.php
@@ -156,6 +156,9 @@ class ReactionRuleConfigTest extends RulesUnitTestBase {
    */
   public function testRemoveEventWithKeyedIndex() {
     // Create a rule with a few events that are numerically indexed.
+    // This situation should not ever happen - the configuration entity
+    // expects that events are numerically indexed and that the indices
+    // are sequential, starting with 0.
     $rule = $this->createRule([
       'events' => [
         2 => ['event_name' => 'foo'],
@@ -163,8 +166,11 @@ class ReactionRuleConfigTest extends RulesUnitTestBase {
       ],
     ]);
     $this->assertSame($rule, $rule->removeEvent('foo'));
+
+    // Removing an event should re-index the events so they are sequential
+    // and start with 0.
     $expected = [
-      3 => ['event_name' => 'bar', 'configuration' => ['qux' => 'baz']],
+      0 => ['event_name' => 'bar', 'configuration' => ['qux' => 'baz']],
     ];
     $this->assertSame($expected, $rule->getEvents());
   }
