diff --git a/src/HotChocolate/Fusion-vnext/src/Fusion.Composition/Logging/LogEntryCodes.cs b/src/HotChocolate/Fusion-vnext/src/Fusion.Composition/Logging/LogEntryCodes.cs
index 23e3fcf4b7e..b806ccb8a5c 100644
--- a/src/HotChocolate/Fusion-vnext/src/Fusion.Composition/Logging/LogEntryCodes.cs
+++ b/src/HotChocolate/Fusion-vnext/src/Fusion.Composition/Logging/LogEntryCodes.cs
@@ -16,6 +16,7 @@ public static class LogEntryCodes
public const string FieldArgumentTypesNotMergeable = "FIELD_ARGUMENT_TYPES_NOT_MERGEABLE";
public const string FieldWithMissingRequiredArgument = "FIELD_WITH_MISSING_REQUIRED_ARGUMENT";
public const string InputFieldDefaultMismatch = "INPUT_FIELD_DEFAULT_MISMATCH";
+ public const string InputFieldReferencesInaccessibleType = "INPUT_FIELD_REFERENCES_INACCESSIBLE_TYPE";
public const string InputFieldTypesNotMergeable = "INPUT_FIELD_TYPES_NOT_MERGEABLE";
public const string InputWithMissingRequiredFields = "INPUT_WITH_MISSING_REQUIRED_FIELDS";
public const string InterfaceFieldNoImplementation = "INTERFACE_FIELD_NO_IMPLEMENTATION";
diff --git a/src/HotChocolate/Fusion-vnext/src/Fusion.Composition/Logging/LogEntryHelper.cs b/src/HotChocolate/Fusion-vnext/src/Fusion.Composition/Logging/LogEntryHelper.cs
index ba3ad608671..a4bfbbf6ab7 100644
--- a/src/HotChocolate/Fusion-vnext/src/Fusion.Composition/Logging/LogEntryHelper.cs
+++ b/src/HotChocolate/Fusion-vnext/src/Fusion.Composition/Logging/LogEntryHelper.cs
@@ -310,6 +310,27 @@ public static LogEntry InputFieldDefaultMismatch(
schemaA);
}
+ public static LogEntry InputFieldReferencesInaccessibleType(
+ MutableInputFieldDefinition field,
+ string typeName,
+ string referenceTypeName,
+ MutableSchemaDefinition schema)
+ {
+ var coordinate = new SchemaCoordinate(typeName, field.Name);
+
+ return new LogEntry(
+ string.Format(
+ LogEntryHelper_InputFieldReferencesInaccessibleType,
+ field.Name,
+ typeName,
+ referenceTypeName),
+ LogEntryCodes.InputFieldReferencesInaccessibleType,
+ LogSeverity.Error,
+ coordinate,
+ field,
+ schema);
+ }
+
public static LogEntry InputFieldTypesNotMergeable(
MutableInputFieldDefinition field,
string typeName,
diff --git a/src/HotChocolate/Fusion-vnext/src/Fusion.Composition/PostMergeValidationRules/InputFieldReferencesInaccessibleTypeRule.cs b/src/HotChocolate/Fusion-vnext/src/Fusion.Composition/PostMergeValidationRules/InputFieldReferencesInaccessibleTypeRule.cs
new file mode 100644
index 00000000000..99f52afa8db
--- /dev/null
+++ b/src/HotChocolate/Fusion-vnext/src/Fusion.Composition/PostMergeValidationRules/InputFieldReferencesInaccessibleTypeRule.cs
@@ -0,0 +1,40 @@
+using HotChocolate.Fusion.Events;
+using HotChocolate.Fusion.Events.Contracts;
+using HotChocolate.Fusion.Extensions;
+using HotChocolate.Types;
+using static HotChocolate.Fusion.Logging.LogEntryHelper;
+
+namespace HotChocolate.Fusion.PostMergeValidationRules;
+
+///
+/// In a composed schema, a field within an input type must only reference types that are exposed.
+/// This requirement guarantees that public types do not reference inaccessible structures
+/// which are intended for internal use.
+///
+///
+/// Specification
+///
+internal sealed class InputFieldReferencesInaccessibleTypeRule : IEventHandler
+{
+ public void Handle(InputFieldEvent @event, CompositionContext context)
+ {
+ var (field, type, schema) = @event;
+
+ if (field.HasFusionInaccessibleDirective())
+ {
+ return;
+ }
+
+ var fieldType = field.Type.AsTypeDefinition();
+
+ if (fieldType.HasFusionInaccessibleDirective())
+ {
+ context.Log.Write(
+ InputFieldReferencesInaccessibleType(
+ field,
+ type.Name,
+ fieldType.Name,
+ schema));
+ }
+ }
+}
diff --git a/src/HotChocolate/Fusion-vnext/src/Fusion.Composition/Properties/CompositionResources.Designer.cs b/src/HotChocolate/Fusion-vnext/src/Fusion.Composition/Properties/CompositionResources.Designer.cs
index 1ed9e0d0ecd..2b5ce908e07 100644
--- a/src/HotChocolate/Fusion-vnext/src/Fusion.Composition/Properties/CompositionResources.Designer.cs
+++ b/src/HotChocolate/Fusion-vnext/src/Fusion.Composition/Properties/CompositionResources.Designer.cs
@@ -572,6 +572,15 @@ internal static string LogEntryHelper_InputFieldDefaultMismatch {
}
}
+ ///
+ /// Looks up a localized string similar to The merged input field '{0}' in type '{1}' cannot reference the inaccessible type '{2}'..
+ ///
+ internal static string LogEntryHelper_InputFieldReferencesInaccessibleType {
+ get {
+ return ResourceManager.GetString("LogEntryHelper_InputFieldReferencesInaccessibleType", resourceCulture);
+ }
+ }
+
///
/// Looks up a localized string similar to The input field '{0}' has a different type shape in schema '{1}' than it does in schema '{2}'..
///
diff --git a/src/HotChocolate/Fusion-vnext/src/Fusion.Composition/Properties/CompositionResources.resx b/src/HotChocolate/Fusion-vnext/src/Fusion.Composition/Properties/CompositionResources.resx
index c3c4b3431fb..85c0f6cb7ca 100644
--- a/src/HotChocolate/Fusion-vnext/src/Fusion.Composition/Properties/CompositionResources.resx
+++ b/src/HotChocolate/Fusion-vnext/src/Fusion.Composition/Properties/CompositionResources.resx
@@ -189,6 +189,9 @@
The default value '{0}' of input field '{1}' in schema '{2}' differs from the default value of '{3}' in schema '{4}'.
+
+ The merged input field '{0}' in type '{1}' cannot reference the inaccessible type '{2}'.
+
The input field '{0}' has a different type shape in schema '{1}' than it does in schema '{2}'.
diff --git a/src/HotChocolate/Fusion-vnext/src/Fusion.Composition/SchemaComposer.cs b/src/HotChocolate/Fusion-vnext/src/Fusion.Composition/SchemaComposer.cs
index 115593fe8fd..ecfa629147b 100644
--- a/src/HotChocolate/Fusion-vnext/src/Fusion.Composition/SchemaComposer.cs
+++ b/src/HotChocolate/Fusion-vnext/src/Fusion.Composition/SchemaComposer.cs
@@ -126,6 +126,7 @@ public CompositionResult Compose()
new EmptyMergedInterfaceTypeRule(),
new EmptyMergedObjectTypeRule(),
new EmptyMergedUnionTypeRule(),
+ new InputFieldReferencesInaccessibleTypeRule(),
new InterfaceFieldNoImplementationRule(),
new NonNullInputFieldIsInaccessibleRule(),
new NoQueriesRule(),
diff --git a/src/HotChocolate/Fusion-vnext/test/Fusion.Composition.Tests/PostMergeValidationRules/InputFieldReferencesInaccessibleTypeRuleTests.cs b/src/HotChocolate/Fusion-vnext/test/Fusion.Composition.Tests/PostMergeValidationRules/InputFieldReferencesInaccessibleTypeRuleTests.cs
new file mode 100644
index 00000000000..8b2c883004c
--- /dev/null
+++ b/src/HotChocolate/Fusion-vnext/test/Fusion.Composition.Tests/PostMergeValidationRules/InputFieldReferencesInaccessibleTypeRuleTests.cs
@@ -0,0 +1,133 @@
+using System.Collections.Immutable;
+using HotChocolate.Fusion.Logging;
+
+namespace HotChocolate.Fusion.PostMergeValidationRules;
+
+public sealed class InputFieldReferencesInaccessibleTypeRuleTests : CompositionTestBase
+{
+ private static readonly object s_rule = new InputFieldReferencesInaccessibleTypeRule();
+ private static readonly ImmutableArray