diff --git a/src/main/metaschema-constraints/oscal-external-constraints.xml b/src/main/metaschema-constraints/oscal-external-constraints.xml
index 650a686e..0e9ee957 100644
--- a/src/main/metaschema-constraints/oscal-external-constraints.xml
+++ b/src/main/metaschema-constraints/oscal-external-constraints.xml
@@ -118,14 +118,13 @@
-
- In-Scope Control Identifiers
- An index of control identifiers that are in-scope for selection in the profile import.
-
-
-
-
-
+
+ In-Scope Control Identifier
+ Each referenced control identifier must match a control in the catalog resolved by the surrounding profile import.
+ Control identifier '{ . }' was not found in the imported catalog.
+
diff --git a/src/test/java/dev/metaschema/oscal/lib/validation/OscalValidationTest.java b/src/test/java/dev/metaschema/oscal/lib/validation/OscalValidationTest.java
index ababfb1c..197d5d2c 100644
--- a/src/test/java/dev/metaschema/oscal/lib/validation/OscalValidationTest.java
+++ b/src/test/java/dev/metaschema/oscal/lib/validation/OscalValidationTest.java
@@ -112,6 +112,42 @@ void testValidateProfileWithMissingControls()
assertFalse(validationResult.isPassing());
}
+ @Test
+ void testValidateProfileWithMultipleImports()
+ throws MetaschemaException, IOException, URISyntaxException, ConstraintValidationException {
+ // Regression test for oscal-cli#250: a profile that imports two catalogs
+ // should validate every with-id against the catalog referenced by the
+ // same import, not against an index built from the first import only.
+ assertMultiImportProfileValidates("src/test/resources/content/issue-250/test-profile.json");
+ }
+
+ @Test
+ void testValidateProfileWithMultipleImportsReversed()
+ throws MetaschemaException, IOException, URISyntaxException, ConstraintValidationException {
+ // Companion regression for oscal-cli#250: the original bug report noted
+ // that reversing the import order moved the errors. This test validates
+ // the same two catalogs with their import order swapped to guard against
+ // any future reintroduction of import-order sensitivity.
+ assertMultiImportProfileValidates("src/test/resources/content/issue-250/test-profile-reversed.json");
+ }
+
+ private void assertMultiImportProfileValidates(@NonNull String profilePath)
+ throws MetaschemaException, IOException, ConstraintValidationException {
+ IBindingContext bindingContext = OscalBindingContext.newInstance();
+
+ IValidationResult validationResult = bindingContext.validateWithConstraints(
+ Paths.get(profilePath).toUri(),
+ null);
+
+ if (validationResult.isPassing()) {
+ LOGGER.info("The resource is valid.");
+ } else {
+ LOGGER.info("Validation identified the following issues:");
+ new LoggingValidationHandler().handleResults(validationResult);
+ }
+ assertTrue(validationResult.isPassing());
+ }
+
private static final class ValidationProvider implements ISchemaValidationProvider {
@NonNull
private final IModule module;
diff --git a/src/test/resources/content/issue-250/test-catalog-ac-1.json b/src/test/resources/content/issue-250/test-catalog-ac-1.json
new file mode 100644
index 00000000..a7434c29
--- /dev/null
+++ b/src/test/resources/content/issue-250/test-catalog-ac-1.json
@@ -0,0 +1,23 @@
+{
+ "catalog": {
+ "uuid": "5f6606a2-5d1f-4df2-8d5e-4c0e7b57bea6",
+ "metadata": {
+ "title": "Minimal AC Family Catalog",
+ "last-modified": "2026-02-25T02:49:04Z",
+ "version": "1.0.0",
+ "oscal-version": "1.2.1"
+ },
+ "controls": [
+ {
+ "id": "ac-1",
+ "title": "Access Control Policy and Procedures",
+ "parts": [
+ {
+ "name": "statement",
+ "prose": "Minimal AC-1 statement used only to validate profile imports."
+ }
+ ]
+ }
+ ]
+ }
+}
diff --git a/src/test/resources/content/issue-250/test-catalog.json b/src/test/resources/content/issue-250/test-catalog.json
new file mode 100644
index 00000000..fdfb6ba0
--- /dev/null
+++ b/src/test/resources/content/issue-250/test-catalog.json
@@ -0,0 +1,23 @@
+{
+ "catalog": {
+ "uuid": "a7167eec-1ab2-4ec3-9921-5680981be857",
+ "metadata": {
+ "title": "Test Catalog",
+ "last-modified": "2026-02-25T02:49:04Z",
+ "version": "1.0.0",
+ "oscal-version": "1.2.1"
+ },
+ "controls": [
+ {
+ "id": "test-01",
+ "title": "TEST CONTROL",
+ "parts": [
+ {
+ "name": "statement",
+ "prose": "Test content"
+ }
+ ]
+ }
+ ]
+ }
+}
diff --git a/src/test/resources/content/issue-250/test-profile-reversed.json b/src/test/resources/content/issue-250/test-profile-reversed.json
new file mode 100644
index 00000000..48643802
--- /dev/null
+++ b/src/test/resources/content/issue-250/test-profile-reversed.json
@@ -0,0 +1,36 @@
+{
+ "profile": {
+ "uuid": "13a94063-d30b-4fc8-bf3b-b75bf9da0b72",
+ "metadata": {
+ "title": "Test Profile (Reversed Imports)",
+ "last-modified": "2026-03-23T00:00:00Z",
+ "version": "1.0.0",
+ "oscal-version": "1.2.1"
+ },
+ "imports": [
+ {
+ "href": "test-catalog.json",
+ "include-controls": [
+ {
+ "with-ids": [
+ "test-01"
+ ]
+ }
+ ]
+ },
+ {
+ "href": "test-catalog-ac-1.json",
+ "include-controls": [
+ {
+ "with-ids": [
+ "ac-1"
+ ]
+ }
+ ]
+ }
+ ],
+ "merge": {
+ "as-is": true
+ }
+ }
+}
diff --git a/src/test/resources/content/issue-250/test-profile.json b/src/test/resources/content/issue-250/test-profile.json
new file mode 100644
index 00000000..7b3fe445
--- /dev/null
+++ b/src/test/resources/content/issue-250/test-profile.json
@@ -0,0 +1,36 @@
+{
+ "profile": {
+ "uuid": "e285521b-890c-4b8e-b0c3-e72fac21a51e",
+ "metadata": {
+ "title": "Test Profile",
+ "last-modified": "2026-03-23T00:00:00Z",
+ "version": "1.0.0",
+ "oscal-version": "1.2.1"
+ },
+ "imports": [
+ {
+ "href": "test-catalog-ac-1.json",
+ "include-controls": [
+ {
+ "with-ids": [
+ "ac-1"
+ ]
+ }
+ ]
+ },
+ {
+ "href": "test-catalog.json",
+ "include-controls": [
+ {
+ "with-ids": [
+ "test-01"
+ ]
+ }
+ ]
+ }
+ ],
+ "merge": {
+ "as-is": true
+ }
+ }
+}