diff --git a/emv2/org.osate.aadl2.errormodel.tests/models/issue2817/.gitignore b/emv2/org.osate.aadl2.errormodel.tests/models/issue2817/.gitignore
new file mode 100644
index 0000000000..afce51184c
--- /dev/null
+++ b/emv2/org.osate.aadl2.errormodel.tests/models/issue2817/.gitignore
@@ -0,0 +1,2 @@
+/.aadlbin-gen/
+/instances/
diff --git a/emv2/org.osate.aadl2.errormodel.tests/models/issue2817/.project b/emv2/org.osate.aadl2.errormodel.tests/models/issue2817/.project
new file mode 100644
index 0000000000..0195361dd2
--- /dev/null
+++ b/emv2/org.osate.aadl2.errormodel.tests/models/issue2817/.project
@@ -0,0 +1,18 @@
+
+
+ issue2817
+
+
+
+
+
+ org.eclipse.xtext.ui.shared.xtextBuilder
+
+
+
+
+
+ org.osate.core.aadlnature
+ org.eclipse.xtext.ui.shared.xtextNature
+
+
diff --git a/emv2/org.osate.aadl2.errormodel.tests/models/issue2817/Issue2817.aadl b/emv2/org.osate.aadl2.errormodel.tests/models/issue2817/Issue2817.aadl
new file mode 100644
index 0000000000..c7ba595ba6
--- /dev/null
+++ b/emv2/org.osate.aadl2.errormodel.tests/models/issue2817/Issue2817.aadl
@@ -0,0 +1,29 @@
+package Issue2817
+public
+ annex EMV2 {**
+ error behavior Machine
+ states
+ state1: initial state;
+ state2: state;
+ end behavior;
+ **};
+
+ system S
+ annex EMV2 {**
+ use types ErrorLibrary;
+ use behavior Issue2817::Machine;
+ component error behavior
+ events
+ typed: error event {CommonErrors};
+ untyped: error event;
+ recovery: recover event;
+ repair1: repair event;
+ transitions
+ typed_event: state1 -[typed {ServiceError} and typed {noerror}]-> state2;
+ untyped_event: state1 -[untyped {noerror}]-> state2;
+ recover_event: state1 -[recovery {noerror}]-> state2;
+ repair_event: state1 -[repair1 {noerror}]-> state2;
+ end component;
+ **};
+ end S;
+end Issue2817;
diff --git a/emv2/org.osate.aadl2.errormodel.tests/models/issue2817/MachineEvents.aadl b/emv2/org.osate.aadl2.errormodel.tests/models/issue2817/MachineEvents.aadl
new file mode 100644
index 0000000000..a00d9180c3
--- /dev/null
+++ b/emv2/org.osate.aadl2.errormodel.tests/models/issue2817/MachineEvents.aadl
@@ -0,0 +1,15 @@
+package MachineEvents
+public
+ annex EMV2 {**
+ error behavior Machine
+ use types ErrorLibrary;
+ events
+ typed: error event {CommonErrors};
+ states
+ state1: initial state;
+ state2: state;
+ transitions
+ state1 -[typed {noerror}]-> state2;
+ end behavior;
+ **};
+end MachineEvents;
diff --git a/emv2/org.osate.aadl2.errormodel.tests/models/issue2817/ValidConditions.aadl b/emv2/org.osate.aadl2.errormodel.tests/models/issue2817/ValidConditions.aadl
new file mode 100644
index 0000000000..06fd794132
--- /dev/null
+++ b/emv2/org.osate.aadl2.errormodel.tests/models/issue2817/ValidConditions.aadl
@@ -0,0 +1,60 @@
+package ValidConditions
+public
+ annex EMV2 {**
+ error behavior Machine
+ states
+ state1: initial state;
+ state2: state;
+ end behavior;
+ **};
+
+ system S
+ features
+ f1: in feature;
+ f2: in feature;
+ annex EMV2 {**
+ use types ErrorLibrary;
+ use behavior ValidConditions::Machine;
+ error propagations
+ f1: in propagation {CommonErrors};
+ f2: in propagation {CommonErrors};
+ end propagations;
+ component error behavior
+ events
+ typed: error event {CommonErrors};
+ untyped: error event;
+ recovery: recover event;
+ repair1: repair event;
+ transitions
+ incoming: state1 -[f1 {ServiceError} and f2 {noerror}]-> state2;
+ typed_event: state1 -[typed {ServiceError}]-> state2;
+ unconstrained_event: state1 -[typed]-> state2;
+ untyped_event: state1 -[untyped]-> state2;
+ recover_event: state1 -[recovery]-> state2;
+ repair_event: state1 -[repair1]-> state2;
+ end component;
+ **};
+ end S;
+
+ system implementation S.i
+ subcomponents
+ child: system Child;
+ annex EMV2 {**
+ component error behavior
+ transitions
+ outgoing: state1 -[child.f {noerror}]-> state2;
+ end component;
+ **};
+ end S.i;
+
+ system Child
+ features
+ f: out feature;
+ annex EMV2 {**
+ use types ErrorLibrary;
+ error propagations
+ f: out propagation {CommonErrors};
+ end propagations;
+ **};
+ end Child;
+end ValidConditions;
diff --git a/emv2/org.osate.aadl2.errormodel.tests/src/org/osate/aadl2/errormodel/tests/issues/Issue2817Test.java b/emv2/org.osate.aadl2.errormodel.tests/src/org/osate/aadl2/errormodel/tests/issues/Issue2817Test.java
new file mode 100644
index 0000000000..2ac595772a
--- /dev/null
+++ b/emv2/org.osate.aadl2.errormodel.tests/src/org/osate/aadl2/errormodel/tests/issues/Issue2817Test.java
@@ -0,0 +1,99 @@
+/**
+ * Copyright (c) 2004-2026 Carnegie Mellon University and others. (see Contributors file).
+ * All Rights Reserved.
+ *
+ * NO WARRANTY. ALL MATERIAL IS FURNISHED ON AN "AS-IS" BASIS. CARNEGIE MELLON UNIVERSITY MAKES NO WARRANTIES OF ANY
+ * KIND, EITHER EXPRESSED OR IMPLIED, AS TO ANY MATTER INCLUDING, BUT NOT LIMITED TO, WARRANTY OF FITNESS FOR PURPOSE
+ * OR MERCHANTABILITY, EXCLUSIVITY, OR RESULTS OBTAINED FROM USE OF THE MATERIAL. CARNEGIE MELLON UNIVERSITY DOES NOT
+ * MAKE ANY WARRANTY OF ANY KIND WITH RESPECT TO FREEDOM FROM PATENT, TRADEMARK, OR COPYRIGHT INFRINGEMENT.
+ *
+ * This program and the accompanying materials are made available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ * Created, in part, with funding and support from the United States Government. (see Acknowledgments file).
+ *
+ * This program includes and/or can make use of certain third party source code, object code, documentation and other
+ * files ("Third Party Software"). The Third Party Software that is used by this program is dependent upon your system
+ * configuration. By using this program, You agree to comply with any and all relevant Third Party Software terms and
+ * conditions contained in any such Third Party Software or separate license file distributed with such Third Party
+ * Software. The parties who own the Third Party Software ("Third Party Licensors") are intended third party benefici-
+ * aries to this license with respect to the terms applicable to their Third Party Software. Third Party Software li-
+ * censes only apply to the Third Party Software and not any other portion of this program or this program as a whole.
+ */
+package org.osate.aadl2.errormodel.tests.issues;
+
+import static org.junit.Assert.assertEquals;
+
+import java.util.ArrayList;
+
+import org.eclipse.xtext.testing.InjectWith;
+import org.eclipse.xtext.testing.XtextRunner;
+import org.eclipse.xtext.testing.validation.ValidationTestHelper;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.osate.aadl2.AadlPackage;
+import org.osate.aadl2.DefaultAnnexLibrary;
+import org.osate.aadl2.DefaultAnnexSubclause;
+import org.osate.aadl2.SystemType;
+import org.osate.aadl2.errormodel.tests.ErrorModelInjectorProvider;
+import org.osate.testsupport.AssertHelper;
+import org.osate.testsupport.TestHelper;
+import org.osate.xtext.aadl2.errormodel.errorModel.AndExpression;
+import org.osate.xtext.aadl2.errormodel.errorModel.ErrorModelLibrary;
+import org.osate.xtext.aadl2.errormodel.errorModel.ErrorModelSubclause;
+
+import com.google.inject.Inject;
+import com.itemis.xtext.testing.FluentIssueCollection;
+import com.itemis.xtext.testing.XtextTest;
+
+@RunWith(XtextRunner.class)
+@InjectWith(ErrorModelInjectorProvider.class)
+public class Issue2817Test extends XtextTest {
+ private static final String PATH = "org.osate.aadl2.errormodel.tests/models/issue2817/";
+ private static final String MESSAGE = "The noerror constraint is not permitted on an event.";
+
+ @Inject
+ private TestHelper testHelper;
+
+ @Inject
+ private ValidationTestHelper validationHelper;
+
+ @Test
+ public void rejectsNoerrorOnComponentEvents() throws Exception {
+ var result = issues = testHelper.testFile(PATH + "Issue2817.aadl");
+ var expected = new FluentIssueCollection(result.getResource(), new ArrayList<>(), new ArrayList<>());
+ var pkg = (AadlPackage) result.getResource().getContents().getFirst();
+ var system = (SystemType) pkg.getPublicSection().getOwnedClassifiers().getFirst();
+ var annex = (ErrorModelSubclause) ((DefaultAnnexSubclause) system.getOwnedAnnexSubclauses().getFirst())
+ .getParsedAnnexSubclause();
+ var conjunction = (AndExpression) annex.getTransitions().get(0).getCondition();
+ AssertHelper.assertError(conjunction.getOperands().get(1), result.getIssues(), expected, MESSAGE);
+ for (int i = 1; i < 4; i++) {
+ AssertHelper.assertError(annex.getTransitions().get(i).getCondition(), result.getIssues(), expected, MESSAGE);
+ }
+ assertEquals(4, result.getIssues().size());
+ expected.sizeIs(4);
+ assertConstraints(expected);
+ }
+
+ @Test
+ public void rejectsNoerrorOnBehaviorMachineEvents() throws Exception {
+ var result = issues = testHelper.testFile(PATH + "MachineEvents.aadl");
+ var expected = new FluentIssueCollection(result.getResource(), new ArrayList<>(), new ArrayList<>());
+ var pkg = (AadlPackage) result.getResource().getContents().getFirst();
+ var library = (ErrorModelLibrary) ((DefaultAnnexLibrary) pkg.getPublicSection().getOwnedAnnexLibraries()
+ .getFirst()).getParsedAnnexLibrary();
+ var condition = library.getBehaviors().getFirst().getTransitions().getFirst().getCondition();
+ AssertHelper.assertError(condition, result.getIssues(), expected, MESSAGE);
+ assertEquals(1, result.getIssues().size());
+ expected.sizeIs(1);
+ assertConstraints(expected);
+ }
+
+ @Test
+ public void acceptsEventTypeConstraintsAndNoerrorOnPropagations() throws Exception {
+ var pkg = testHelper.parseFile(PATH + "ValidConditions.aadl");
+ validationHelper.assertNoIssues(pkg);
+ }
+}
diff --git a/emv2/org.osate.xtext.aadl2.errormodel/src/org/osate/xtext/aadl2/errormodel/validation/ErrorModelValidator.java b/emv2/org.osate.xtext.aadl2.errormodel/src/org/osate/xtext/aadl2/errormodel/validation/ErrorModelValidator.java
index 821454b3d5..df3c42fd96 100644
--- a/emv2/org.osate.xtext.aadl2.errormodel/src/org/osate/xtext/aadl2/errormodel/validation/ErrorModelValidator.java
+++ b/emv2/org.osate.xtext.aadl2.errormodel/src/org/osate/xtext/aadl2/errormodel/validation/ErrorModelValidator.java
@@ -547,7 +547,9 @@ private void checkConditionElementType(ConditionElement conditionElement) {
if (condTS == null) {
return;
}
- if (triggerTS == null && condTS != null) {
+ if (ep instanceof ErrorBehaviorEvent && EMV2TypeSetUtil.isNoError(condTS)) {
+ error(conditionElement, "The noerror constraint is not permitted on an event.");
+ } else if (triggerTS == null && condTS != null) {
// it is ok for a state not to have a type set.
error(conditionElement, "Condition has type constraint but referenced " + triggerName + " does not.");
} else if (!EMV2TypeSetUtil.isNoError(condTS) && !EMV2TypeSetUtil.contains(triggerTS, condTS)) {