diff --git a/src/HotChocolate/Fusion/src/Fusion.Composition/Options/SatisfiabilityOptions.cs b/src/HotChocolate/Fusion/src/Fusion.Composition/Options/SatisfiabilityOptions.cs
index 03ee555fef6..71510855e78 100644
--- a/src/HotChocolate/Fusion/src/Fusion.Composition/Options/SatisfiabilityOptions.cs
+++ b/src/HotChocolate/Fusion/src/Fusion.Composition/Options/SatisfiabilityOptions.cs
@@ -13,7 +13,8 @@ public sealed class SatisfiabilityOptions
///
/// A collection of fields that should be ignored during the satisfiability analysis
/// because they are known to be non-accessible. The key is the qualified field name (e.g.
- /// "TypeName.fieldName") and the value is a list of paths to ignore for that field.
+ /// "TypeName.fieldName") and the value is a list of paths to ignore for that field. A listed
+ /// field is also exempt from the UNREACHABLE_SOURCE_FIELD error.
///
public Dictionary> IgnoredNonAccessibleFields { get; } = [];
}
diff --git a/src/HotChocolate/Fusion/src/Fusion.Composition/PostMergeValidationRules/UnreachableSourceFieldRule.cs b/src/HotChocolate/Fusion/src/Fusion.Composition/PostMergeValidationRules/UnreachableSourceFieldRule.cs
index 9618216f1a7..defdc1edb92 100644
--- a/src/HotChocolate/Fusion/src/Fusion.Composition/PostMergeValidationRules/UnreachableSourceFieldRule.cs
+++ b/src/HotChocolate/Fusion/src/Fusion.Composition/PostMergeValidationRules/UnreachableSourceFieldRule.cs
@@ -2,6 +2,7 @@
using HotChocolate.Fusion.Events.Contracts;
using HotChocolate.Fusion.Extensions;
using HotChocolate.Fusion.Features;
+using HotChocolate.Fusion.Options;
using HotChocolate.Types;
using HotChocolate.Types.Mutable;
using static HotChocolate.Fusion.Logging.LogEntryHelper;
@@ -13,10 +14,16 @@ namespace HotChocolate.Fusion.PostMergeValidationRules;
///
/// A field declared on a type that its source schema cannot reach from its root types must be
/// resolved by another source schema whenever clients can reach the type in the composite schema.
-/// Otherwise, composition fails with an UNREACHABLE_SOURCE_FIELD error.
+/// Otherwise, composition fails with an UNREACHABLE_SOURCE_FIELD error, unless the field
+/// coordinate is listed in .
///
-internal sealed class UnreachableSourceFieldRule : IEventHandler
+internal sealed class UnreachableSourceFieldRule(
+ IReadOnlyDictionary> ignoredNonAccessibleFields)
+ : IEventHandler
{
+ private readonly IReadOnlyDictionary> _ignoredNonAccessibleFields =
+ ignoredNonAccessibleFields;
+
public void Handle(SchemaEvent @event, CompositionContext context)
{
var mergedSchema = @event.Schema;
@@ -65,6 +72,12 @@ public void Handle(SchemaEvent @event, CompositionContext context)
continue;
}
+ // An ignored non-accessible field is exempt whatever paths are listed for it.
+ if (_ignoredNonAccessibleFields.ContainsKey($"{type.Name}.{field.Name}"))
+ {
+ continue;
+ }
+
context.Log.Write(UnreachableSourceField(field, type, schema));
}
}
diff --git a/src/HotChocolate/Fusion/src/Fusion.Composition/SchemaComposer.cs b/src/HotChocolate/Fusion/src/Fusion.Composition/SchemaComposer.cs
index 24aceba838f..db60e474c00 100644
--- a/src/HotChocolate/Fusion/src/Fusion.Composition/SchemaComposer.cs
+++ b/src/HotChocolate/Fusion/src/Fusion.Composition/SchemaComposer.cs
@@ -203,7 +203,8 @@ public CompositionResult Compose()
// Post Merge Validation
var postMergeValidationResult =
- new PostMergeValidator(mergedSchema, PostMergeRules, schemas, _log).Validate();
+ new PostMergeValidator(mergedSchema, CreatePostMergeRules(_schemaComposerOptions), schemas, _log)
+ .Validate();
if (postMergeValidationResult.IsFailure)
{
@@ -339,9 +340,10 @@ internal static ImmutableArray