Skip to main content

apollo_federation/error/
mod.rs

1pub(crate) mod suggestion;
2
3use std::cmp::Ordering;
4use std::fmt::Display;
5use std::fmt::Formatter;
6use std::fmt::Write;
7use std::ops::Range;
8use std::sync::LazyLock;
9
10use apollo_compiler::InvalidNameError;
11use apollo_compiler::Name;
12use apollo_compiler::ast::OperationType;
13use apollo_compiler::parser::LineColumn;
14use apollo_compiler::validation::DiagnosticList;
15use apollo_compiler::validation::WithErrors;
16
17use crate::subgraph::SubgraphError;
18use crate::subgraph::spec::FederationSpecError;
19use crate::subgraph::typestate::HasMetadata;
20use crate::subgraph::typestate::Subgraph;
21
22/// Create an internal error.
23///
24/// # Example
25/// ```rust
26/// use apollo_federation::internal_error;
27/// use apollo_federation::error::FederationError;
28/// # fn may_be_none() -> Option<()> { None }
29///
30/// const NAME: &str = "the thing";
31/// let result: Result<(), FederationError> = may_be_none()
32///     .ok_or_else(|| internal_error!("Expected {NAME} to be Some"));
33/// ```
34#[macro_export]
35macro_rules! internal_error {
36    ( $( $arg:tt )+ ) => {
37        $crate::error::FederationError::internal(format!( $( $arg )+ ))
38    }
39}
40
41/// Break out of the current function, returning an internal error.
42///
43/// # Example
44/// ```rust
45/// use apollo_federation::bail;
46/// use apollo_federation::error::FederationError;
47/// # fn may_be_none() -> Option<()> { None }
48///
49/// fn example() -> Result<(), FederationError> {
50///     bail!("Something went horribly wrong");
51///     unreachable!()
52/// }
53/// #
54/// # _ = example();
55/// ```
56#[macro_export]
57macro_rules! bail {
58    ( $( $arg:tt )+ ) => {
59        return Err($crate::internal_error!( $( $arg )+ ).into())
60    }
61}
62
63/// A safe assertion: in debug mode, it panicks on failure, and in production, it returns an
64/// internal error.
65///
66/// Treat this as an assertion. It must only be used for conditions that *should never happen*
67/// in normal operation.
68///
69/// # Example
70/// ```rust,no_run
71/// use apollo_federation::ensure;
72/// use apollo_federation::error::FederationError;
73/// # fn may_be_none() -> Option<()> { None }
74///
75/// fn example() -> Result<(), FederationError> {
76///     ensure!(1 == 0, "Something went horribly wrong");
77///     unreachable!()
78/// }
79/// ```
80#[macro_export]
81macro_rules! ensure {
82    ( $expr:expr, $( $arg:tt )+ ) => {
83        #[cfg(debug_assertions)]
84        {
85            if false {
86                return Err($crate::error::FederationError::internal("ensure!() must be used in a function that returns a Result").into());
87            }
88            assert!($expr, $( $arg )+);
89        }
90
91        #[cfg(not(debug_assertions))]
92        if !$expr {
93            $crate::bail!( $( $arg )+ );
94        }
95    }
96}
97
98// What we really needed here was the string representations in enum form, this isn't meant to
99// replace AST components.
100#[derive(Clone, Debug, strum_macros::Display)]
101enum SchemaRootKind {
102    #[strum(to_string = "query")]
103    Query,
104    #[strum(to_string = "mutation")]
105    Mutation,
106    #[strum(to_string = "subscription")]
107    Subscription,
108}
109
110impl From<SchemaRootKind> for String {
111    fn from(value: SchemaRootKind) -> Self {
112        value.to_string()
113    }
114}
115
116#[derive(Clone, Debug, strum_macros::Display, PartialEq, Eq)]
117pub enum UnsupportedFeatureKind {
118    #[strum(to_string = "alias")]
119    Alias,
120}
121
122/// Modeled after `SubgraphLocation` defined in `apollo_composition`, so this struct can be
123/// converted to it.
124#[derive(Clone, Debug)]
125pub struct SubgraphLocation {
126    /// Subgraph name
127    pub subgraph: String, // TODO: Change this to `Arc<str>`, once `Merger` is updated.
128    /// Source code range in the subgraph schema document
129    pub range: Range<LineColumn>,
130}
131
132pub type Locations = Vec<SubgraphLocation>;
133
134/// Supergraph coordinates carried on `@inaccessible` API schema errors so composition can attach
135/// subgraph source locations (port of JS `inaccessible_elements` / `inaccessible_referencers`
136/// extensions and `updateInaccessibleErrorsWithLinkToSubgraphs`). Those locations are surfaced on
137/// [`CompositionError::MergeError`] as [`SubgraphLocation`] entries (Rust equivalent of JS
138/// `withModifiedErrorNodes`).
139#[derive(Clone, Debug, Default)]
140pub struct InaccessibleCompositionLinks {
141    pub elements: Vec<String>,
142    pub referencers: Vec<String>,
143}
144
145pub(crate) trait HasLocations {
146    fn locations<T: HasMetadata>(&self, subgraph: &Subgraph<T>) -> Locations;
147}
148
149impl<HL: HasLocations> HasLocations for &HL {
150    fn locations<T: HasMetadata>(&self, subgraph: &Subgraph<T>) -> Locations {
151        HL::locations(self, subgraph)
152    }
153}
154
155#[derive(Debug, Clone, thiserror::Error)]
156pub enum CompositionError {
157    #[error("[{subgraph}] {error}")]
158    SubgraphError {
159        subgraph: String,
160        error: SingleFederationError,
161        locations: Locations,
162    },
163    #[error("{error}")]
164    MergeError {
165        error: SingleFederationError,
166        locations: Locations,
167    },
168    #[error("{error}")]
169    MergeValidationError { error: SingleFederationError },
170    #[error("{message}")]
171    ContextualArgumentNotContextualInAllSubgraphs {
172        message: String,
173        locations: Locations,
174    },
175    #[error("{message}")]
176    EmptyMergedEnumType {
177        message: String,
178        locations: Locations,
179    },
180    #[error("{message}")]
181    EnumValueMismatch { message: String },
182    #[error("{message}")]
183    ExternalArgumentTypeMismatch { message: String },
184    #[error("{message}")]
185    ExternalTypeMismatch { message: String },
186    #[error("{message}")]
187    ExternalArgumentDefaultMismatch { message: String },
188    #[error("{message}")]
189    InvalidGraphQL { message: String },
190    #[error(transparent)]
191    InvalidGraphQLName(InvalidNameError),
192    #[error(r#"{message} in @fromContext substring "{context}""#)]
193    FromContextParseError { context: String, message: String },
194    #[error(
195        "Unsupported custom directive @{name} on fragment spread. Due to query transformations during planning, the router requires directives on fragment spreads to support both the FRAGMENT_SPREAD and INLINE_FRAGMENT locations."
196    )]
197    UnsupportedSpreadDirective { name: Name },
198    #[error("{message}")]
199    DirectiveDefinitionInvalid { message: String },
200    #[error("{message}")]
201    TypeDefinitionInvalid { message: String },
202    #[error("{message}")]
203    InterfaceObjectUsageError { message: String },
204    #[error("{message}")]
205    InterfaceKeyMissingImplementationType { message: String },
206    #[error("{message}")]
207    TypeKindMismatch { message: String },
208    #[error("{message}")]
209    ShareableHasMismatchedRuntimeTypes { message: String },
210    #[error("{message}")]
211    SatisfiabilityError { message: String },
212    #[error("{message}")]
213    MaxValidationSubgraphPathsExceeded { message: String },
214    #[error("{message}")]
215    InternalError { message: String },
216    #[error("{message}")]
217    ExternalArgumentMissing { message: String },
218    #[error("{message}")]
219    ExternalMissingOnBase { message: String },
220    #[error("{message}")]
221    MergedDirectiveApplicationOnExternal { message: String },
222    #[error("{message}")]
223    LinkImportNameMismatch { message: String },
224    #[error("{message}")]
225    InvalidFieldSharing {
226        message: String,
227        locations: Locations,
228    },
229    #[error(
230        "[{subgraph}] Type \"{dest}\" is an extension type, but there is no type definition for \"{dest}\" in any subgraph."
231    )]
232    ExtensionWithNoBase {
233        subgraph: String,
234        dest: String,
235        locations: Locations,
236    },
237    #[error("{message}")]
238    DirectiveCompositionError { message: String },
239    #[error("{message}")]
240    InconsistentInputObjectField { message: String },
241    #[error("{message}")]
242    RequiredArgumentMissingInSomeSubgraph {
243        message: String,
244        locations: Locations,
245    },
246    #[error("{message}")]
247    RequiredInputFieldMissingInSomeSubgraph {
248        message: String,
249        locations: Locations,
250    },
251    #[error("{message}")]
252    EmptyMergedInputType {
253        message: String,
254        locations: Locations,
255    },
256    #[error("{message}")]
257    InputFieldMergeFailed {
258        message: String,
259        locations: Locations,
260    },
261    #[error("{message}")]
262    FieldArgumentTypeMismatch { message: String },
263    #[error("{message}")]
264    FieldTypeMismatch { message: String },
265    #[error("{message}")]
266    OverrideCollisionWithAnotherDirective { message: String },
267    #[error("{message}")]
268    OverrideFromSelfError { message: String },
269    #[error("{message}")]
270    OverrideLabelInvalid { message: String },
271    #[error("{message}")]
272    OverrideOnInterface { message: String },
273    #[error("{message}")]
274    OverrideSourceHasOverride { message: String },
275    #[error("{message}")]
276    QueryRootMissing { message: String },
277    #[error("{message}")]
278    ArgumentDefaultMismatch {
279        message: String,
280        locations: Locations,
281    },
282    #[error("{message}")]
283    InputFieldDefaultMismatch {
284        message: String,
285        locations: Locations,
286    },
287    #[error("{message}")]
288    InterfaceFieldNoImplem { message: String },
289}
290
291impl CompositionError {
292    pub fn code(&self) -> ErrorCode {
293        match self {
294            Self::SubgraphError { error, .. } => error.code(),
295            Self::MergeError { error, .. } => error.code(),
296            Self::MergeValidationError { error, .. } => error.code(),
297            Self::ContextualArgumentNotContextualInAllSubgraphs { .. } => {
298                ErrorCode::ContextualArgumentNotContextualInAllSubgraphs
299            }
300            Self::EmptyMergedEnumType { .. } => ErrorCode::EmptyMergedEnumType,
301            Self::EnumValueMismatch { .. } => ErrorCode::EnumValueMismatch,
302            Self::ExternalTypeMismatch { .. } => ErrorCode::ExternalTypeMismatch,
303            Self::ExternalArgumentTypeMismatch { .. } => ErrorCode::ExternalArgumentTypeMismatch,
304            Self::ExternalArgumentDefaultMismatch { .. } => {
305                ErrorCode::ExternalArgumentDefaultMismatch
306            }
307            Self::InvalidGraphQL { .. } => ErrorCode::InvalidGraphQL,
308            Self::InvalidGraphQLName(..) => ErrorCode::InvalidGraphQL,
309            Self::FromContextParseError { .. } => ErrorCode::InvalidGraphQL,
310            Self::UnsupportedSpreadDirective { .. } => ErrorCode::InvalidGraphQL,
311            Self::DirectiveDefinitionInvalid { .. } => ErrorCode::DirectiveDefinitionInvalid,
312            Self::TypeDefinitionInvalid { .. } => ErrorCode::TypeDefinitionInvalid,
313            Self::InterfaceObjectUsageError { .. } => ErrorCode::InterfaceObjectUsageError,
314            Self::InterfaceKeyMissingImplementationType { .. } => {
315                ErrorCode::InterfaceKeyMissingImplementationType
316            }
317            Self::TypeKindMismatch { .. } => ErrorCode::TypeKindMismatch,
318            Self::ShareableHasMismatchedRuntimeTypes { .. } => {
319                ErrorCode::ShareableHasMismatchedRuntimeTypes
320            }
321            Self::SatisfiabilityError { .. } => ErrorCode::SatisfiabilityError,
322            Self::MaxValidationSubgraphPathsExceeded { .. } => {
323                ErrorCode::MaxValidationSubgraphPathsExceeded
324            }
325            Self::InternalError { .. } => ErrorCode::Internal,
326            Self::ExternalArgumentMissing { .. } => ErrorCode::ExternalArgumentMissing,
327            Self::ExternalMissingOnBase { .. } => ErrorCode::ExternalMissingOnBase,
328            Self::MergedDirectiveApplicationOnExternal { .. } => {
329                ErrorCode::MergedDirectiveApplicationOnExternal
330            }
331            Self::LinkImportNameMismatch { .. } => ErrorCode::LinkImportNameMismatch,
332            Self::InvalidFieldSharing { .. } => ErrorCode::InvalidFieldSharing,
333            Self::InconsistentInputObjectField { .. } => ErrorCode::Internal, // This is for hints, not errors
334            Self::RequiredArgumentMissingInSomeSubgraph { .. } => {
335                ErrorCode::RequiredArgumentMissingInSomeSubgraph
336            }
337            Self::RequiredInputFieldMissingInSomeSubgraph { .. } => {
338                ErrorCode::RequiredInputFieldMissingInSomeSubgraph
339            }
340            Self::EmptyMergedInputType { .. } => ErrorCode::EmptyMergedInputType,
341            Self::InputFieldMergeFailed { .. } => ErrorCode::InputFieldMergeFailed,
342            Self::ExtensionWithNoBase { .. } => ErrorCode::ExtensionWithNoBase,
343            Self::DirectiveCompositionError { .. } => ErrorCode::DirectiveCompositionError,
344            Self::FieldArgumentTypeMismatch { .. } => ErrorCode::FieldArgumentTypeMismatch,
345            Self::FieldTypeMismatch { .. } => ErrorCode::FieldTypeMismatch,
346            Self::OverrideCollisionWithAnotherDirective { .. } => {
347                ErrorCode::OverrideCollisionWithAnotherDirective
348            }
349            Self::OverrideFromSelfError { .. } => ErrorCode::OverrideFromSelfError,
350            Self::OverrideLabelInvalid { .. } => ErrorCode::OverrideLabelInvalid,
351            Self::OverrideOnInterface { .. } => ErrorCode::OverrideOnInterface,
352            Self::OverrideSourceHasOverride { .. } => ErrorCode::OverrideSourceHasOverride,
353            Self::QueryRootMissing { .. } => ErrorCode::QueryRootMissing,
354            Self::ArgumentDefaultMismatch { .. } => ErrorCode::FieldArgumentDefaultMismatch,
355            Self::InputFieldDefaultMismatch { .. } => ErrorCode::InputFieldDefaultMismatch,
356            Self::InterfaceFieldNoImplem { .. } => ErrorCode::InterfaceFieldNoImplem,
357        }
358    }
359
360    pub(crate) fn append_message(self, appendix: impl Display) -> Self {
361        match self {
362            Self::EmptyMergedEnumType { message, locations } => Self::EmptyMergedEnumType {
363                message: format!("{message}{appendix}"),
364                locations,
365            },
366            Self::EnumValueMismatch { message } => Self::EnumValueMismatch {
367                message: format!("{message}{appendix}"),
368            },
369            Self::ExternalTypeMismatch { message } => Self::ExternalTypeMismatch {
370                message: format!("{message}{appendix}"),
371            },
372            Self::ExternalArgumentTypeMismatch { message } => Self::ExternalArgumentTypeMismatch {
373                message: format!("{message}{appendix}"),
374            },
375            Self::ExternalArgumentDefaultMismatch { message } => {
376                Self::ExternalArgumentDefaultMismatch {
377                    message: format!("{message}{appendix}"),
378                }
379            }
380            Self::InvalidGraphQL { message } => Self::InvalidGraphQL {
381                message: format!("{message}{appendix}"),
382            },
383            Self::DirectiveDefinitionInvalid { message } => Self::DirectiveDefinitionInvalid {
384                message: format!("{message}{appendix}"),
385            },
386            Self::TypeDefinitionInvalid { message } => Self::TypeDefinitionInvalid {
387                message: format!("{message}{appendix}"),
388            },
389            Self::InterfaceObjectUsageError { message } => Self::InterfaceObjectUsageError {
390                message: format!("{message}{appendix}"),
391            },
392            Self::InterfaceKeyMissingImplementationType { message } => {
393                Self::InterfaceKeyMissingImplementationType {
394                    message: format!("{message}{appendix}"),
395                }
396            }
397            Self::TypeKindMismatch { message } => Self::TypeKindMismatch {
398                message: format!("{message}{appendix}"),
399            },
400            Self::ShareableHasMismatchedRuntimeTypes { message } => {
401                Self::ShareableHasMismatchedRuntimeTypes {
402                    message: format!("{message}{appendix}"),
403                }
404            }
405            Self::SatisfiabilityError { message } => Self::SatisfiabilityError {
406                message: format!("{message}{appendix}"),
407            },
408            Self::MaxValidationSubgraphPathsExceeded { message } => {
409                Self::MaxValidationSubgraphPathsExceeded {
410                    message: format!("{message}{appendix}"),
411                }
412            }
413            Self::InternalError { message } => Self::InternalError {
414                message: format!("{message}{appendix}"),
415            },
416            Self::ExternalArgumentMissing { message } => Self::ExternalArgumentMissing {
417                message: format!("{message}{appendix}"),
418            },
419            Self::ExternalMissingOnBase { message } => Self::ExternalMissingOnBase {
420                message: format!("{message}{appendix}"),
421            },
422            Self::MergedDirectiveApplicationOnExternal { message } => {
423                Self::MergedDirectiveApplicationOnExternal {
424                    message: format!("{message}{appendix}"),
425                }
426            }
427            Self::LinkImportNameMismatch { message } => Self::LinkImportNameMismatch {
428                message: format!("{message}{appendix}"),
429            },
430            Self::InvalidFieldSharing { message, locations } => Self::InvalidFieldSharing {
431                message: format!("{message}{appendix}"),
432                locations,
433            },
434            Self::DirectiveCompositionError { message } => Self::DirectiveCompositionError {
435                message: format!("{message}{appendix}"),
436            },
437            Self::InconsistentInputObjectField { message } => Self::InconsistentInputObjectField {
438                message: format!("{message}{appendix}"),
439            },
440            Self::RequiredArgumentMissingInSomeSubgraph { message, locations } => {
441                Self::RequiredArgumentMissingInSomeSubgraph {
442                    message: format!("{message}{appendix}"),
443                    locations,
444                }
445            }
446            Self::RequiredInputFieldMissingInSomeSubgraph { message, locations } => {
447                Self::RequiredInputFieldMissingInSomeSubgraph {
448                    message: format!("{message}{appendix}"),
449                    locations,
450                }
451            }
452            Self::EmptyMergedInputType { message, locations } => Self::EmptyMergedInputType {
453                message: format!("{message}{appendix}"),
454                locations,
455            },
456            Self::InputFieldMergeFailed { message, locations } => Self::InputFieldMergeFailed {
457                message: format!("{message}{appendix}"),
458                locations,
459            },
460            Self::FieldArgumentTypeMismatch { message } => Self::FieldArgumentTypeMismatch {
461                message: format!("{message}{appendix}"),
462            },
463            Self::FieldTypeMismatch { message } => Self::FieldTypeMismatch {
464                message: format!("{message}{appendix}"),
465            },
466            Self::ContextualArgumentNotContextualInAllSubgraphs { message, locations } => {
467                Self::ContextualArgumentNotContextualInAllSubgraphs {
468                    message: format!("{message}{appendix}"),
469                    locations,
470                }
471            }
472            Self::ArgumentDefaultMismatch { message, locations } => Self::ArgumentDefaultMismatch {
473                message: format!("{message}{appendix}"),
474                locations,
475            },
476            Self::InputFieldDefaultMismatch { message, locations } => {
477                Self::InputFieldDefaultMismatch {
478                    message: format!("{message}{appendix}"),
479                    locations,
480                }
481            }
482            Self::InterfaceFieldNoImplem { message } => Self::InterfaceFieldNoImplem {
483                message: format!("{message}{appendix}"),
484            },
485            // Remaining errors do not have an obvious way to appending a message, so we just return self.
486            Self::SubgraphError { .. }
487            | Self::MergeError { .. }
488            | Self::MergeValidationError { .. }
489            | Self::InvalidGraphQLName(..)
490            | Self::FromContextParseError { .. }
491            | Self::UnsupportedSpreadDirective { .. }
492            | Self::ExtensionWithNoBase { .. }
493            | Self::OverrideCollisionWithAnotherDirective { .. }
494            | Self::OverrideFromSelfError { .. }
495            | Self::OverrideLabelInvalid { .. }
496            | Self::OverrideOnInterface { .. }
497            | Self::OverrideSourceHasOverride { .. }
498            | Self::QueryRootMissing { .. } => self,
499        }
500    }
501
502    pub(crate) fn append_locations(
503        mut self,
504        new_locations: impl IntoIterator<Item = SubgraphLocation>,
505    ) -> Self {
506        match &mut self {
507            Self::SubgraphError { locations, .. }
508            | Self::EmptyMergedEnumType { locations, .. }
509            | Self::InputFieldMergeFailed { locations, .. }
510            | Self::ExtensionWithNoBase { locations, .. }
511            | Self::RequiredArgumentMissingInSomeSubgraph { locations, .. }
512            | Self::RequiredInputFieldMissingInSomeSubgraph { locations, .. }
513            | Self::EmptyMergedInputType { locations, .. }
514            | Self::InvalidFieldSharing { locations, .. }
515            | Self::MergeError { locations, .. }
516            | Self::ArgumentDefaultMismatch { locations, .. }
517            | Self::InputFieldDefaultMismatch { locations, .. } => locations.extend(new_locations),
518            // Remaining errors do not have an obvious way to appending locations, so we do nothing
519            _ => {}
520        }
521        self
522    }
523
524    pub fn locations(&self) -> &[SubgraphLocation] {
525        match self {
526            Self::SubgraphError { locations, .. }
527            | Self::EmptyMergedEnumType { locations, .. }
528            | Self::InputFieldMergeFailed { locations, .. }
529            | Self::ExtensionWithNoBase { locations, .. }
530            | Self::RequiredArgumentMissingInSomeSubgraph { locations, .. }
531            | Self::RequiredInputFieldMissingInSomeSubgraph { locations, .. }
532            | Self::EmptyMergedInputType { locations, .. }
533            | Self::InvalidFieldSharing { locations, .. }
534            | Self::MergeError { locations, .. }
535            | Self::ArgumentDefaultMismatch { locations, .. }
536            | Self::InputFieldDefaultMismatch { locations, .. } => locations,
537            _ => &[],
538        }
539    }
540}
541
542impl SubgraphError {
543    pub fn to_composition_errors(&self) -> impl Iterator<Item = CompositionError> {
544        self.errors
545            .iter()
546            .map(move |error| CompositionError::SubgraphError {
547                subgraph: self.subgraph.clone(),
548                error: error.error.clone(),
549                locations: error
550                    .locations
551                    .iter()
552                    .map(|range| SubgraphLocation {
553                        subgraph: self.subgraph.clone(),
554                        range: range.clone(),
555                    })
556                    .collect(),
557            })
558    }
559}
560
561/* TODO(@tylerbloom): This is currently not needed. SingleFederation errors are aggregated using
562 * MultipleFederationErrors. This is then turned into a FederationError, then in a SubgraphError,
563 * and finally into a CompositionError. Not implementing this yet also ensures that any
564 * SingleFederationErrors that are intented on becoming SubgraphErrors still do.
565impl<E: Into<FederationError>> From<E> for SingleCompositionError {
566    fn from(_value: E) -> Self {
567        todo!()
568    }
569}
570*/
571
572#[derive(Debug, Clone, thiserror::Error)]
573pub enum SingleFederationError {
574    #[error(
575        "An internal error has occurred, please report this bug to Apollo.\n\nDetails: {message}"
576    )]
577    Internal { message: String },
578    #[error("An internal error has occurred, please report this bug to Apollo. Details: {0}")]
579    #[allow(private_interfaces)] // users should not inspect this.
580    InternalRebaseError(#[from] crate::operation::RebaseError),
581    // This is a known bug that will take time to fix, and does not require reporting.
582    #[error("{message}")]
583    InternalUnmergeableFields { message: String },
584    // InvalidGraphQL: We need to be able to modify the message text from apollo-compiler. So, we
585    //                 format the DiagnosticData into String here. We can add additional data as
586    //                 necessary.
587    #[error("{message}")]
588    InvalidGraphQL { message: String },
589    #[error(transparent)]
590    InvalidGraphQLName(#[from] InvalidNameError),
591    #[error("Subgraph invalid: {message}")]
592    InvalidSubgraph { message: String },
593    #[error("Operation name not found")]
594    UnknownOperation,
595    #[error("Must provide operation name if query contains multiple operations")]
596    OperationNameNotProvided,
597    #[error(r#"{message} in @fromContext substring "{context}""#)]
598    FromContextParseError { context: String, message: String },
599    #[error(
600        "Unsupported custom directive @{name} on fragment spread. Due to query transformations during planning, the router requires directives on fragment spreads to support both the FRAGMENT_SPREAD and INLINE_FRAGMENT locations."
601    )]
602    UnsupportedSpreadDirective { name: Name },
603    #[error("{message}")]
604    DirectiveDefinitionInvalid { message: String },
605    #[error("{message}")]
606    TypeDefinitionInvalid { message: String },
607    #[error("{message}")]
608    UnsupportedFederationDirective { message: String },
609    #[error("{message}")]
610    UnsupportedFederationVersion { message: String },
611    #[error("{message}")]
612    UnsupportedLinkedFeature { message: String },
613    #[error("{message}")]
614    UnknownFederationLinkVersion { message: String },
615    #[error("{message}")]
616    UnknownLinkVersion { message: String },
617    #[error(
618        "On type \"{target_type}\", for {application}: field {inner_coordinate} cannot be included because it has arguments (fields with argument are not allowed in @key)"
619    )]
620    KeyFieldsHasArgs {
621        target_type: Name,
622        application: String,
623        inner_coordinate: String,
624    },
625    #[error(
626        "On field \"{coordinate}\", for {application}: field {inner_coordinate} cannot be included because it has arguments (fields with argument are not allowed in @provides)"
627    )]
628    ProvidesFieldsHasArgs {
629        coordinate: String,
630        application: String,
631        inner_coordinate: String,
632    },
633    #[error("On field \"{coordinate}\", for {application}: {message}")]
634    ProvidesFieldsMissingExternal {
635        coordinate: String,
636        application: String,
637        message: String,
638    },
639    #[error("On field \"{coordinate}\", for {application}: {message}")]
640    RequiresFieldsMissingExternal {
641        coordinate: String,
642        application: String,
643        message: String,
644    },
645    #[error("{message}")]
646    KeyUnsupportedOnInterface { message: String },
647    #[error("{message}")]
648    ProvidesUnsupportedOnInterface { message: String },
649    #[error("{message}")]
650    RequiresUnsupportedOnInterface { message: String },
651    #[error(
652        "On type \"{target_type}\", for {application}: cannot have directive applications in the @key(fields:) argument but found {applied_directives}."
653    )]
654    KeyHasDirectiveInFieldsArg {
655        target_type: Name,
656        application: String,
657        applied_directives: String,
658    },
659    #[error(
660        "On field \"{coordinate}\", for {application}: cannot have directive applications in the @provides(fields:) argument but found {applied_directives}."
661    )]
662    ProvidesHasDirectiveInFieldsArg {
663        coordinate: String,
664        application: String,
665        applied_directives: String,
666    },
667    #[error(
668        "On field \"{coordinate}\", for {application}: cannot have directive applications in the @requires(fields:) argument but found {applied_directives}."
669    )]
670    RequiresHasDirectiveInFieldsArg {
671        coordinate: String,
672        application: String,
673        applied_directives: String,
674    },
675    #[error("{message}")]
676    ExternalUnused { message: String },
677    #[error(
678        "Type {type_name} contains only external fields and all those fields are all unused (they do not appear in any @key, @provides or @requires)."
679    )]
680    TypeWithOnlyUnusedExternal { type_name: Name },
681    #[error("{message}")]
682    ProvidesOnNonObjectField { message: String },
683    #[error(
684        "On type \"{target_type}\", for {application}: Invalid value for argument \"fields\": must be a string."
685    )]
686    KeyInvalidFieldsType {
687        target_type: Name,
688        application: String,
689    },
690    #[error(
691        "On field \"{coordinate}\", for {application}: Invalid value for argument \"fields\": must be a string."
692    )]
693    ProvidesInvalidFieldsType {
694        coordinate: String,
695        application: String,
696    },
697    #[error(
698        "On field \"{coordinate}\", for {application}: Invalid value for argument \"fields\": must be a string."
699    )]
700    RequiresInvalidFieldsType {
701        coordinate: String,
702        application: String,
703    },
704    #[error("On type \"{target_type}\", for {application}: {message}")]
705    KeyInvalidFields {
706        target_type: Name,
707        application: String,
708        message: String,
709    },
710    #[error("On field \"{coordinate}\", for {application}: {message}")]
711    ProvidesInvalidFields {
712        coordinate: String,
713        application: String,
714        message: String,
715    },
716    #[error("On field \"{coordinate}\", for {application}: {message}")]
717    RequiresInvalidFields {
718        coordinate: String,
719        application: String,
720        message: String,
721    },
722    #[error("On type \"{target_type}\", for {application}: {message}")]
723    KeyFieldsSelectInvalidType {
724        target_type: Name,
725        application: String,
726        message: String,
727    },
728    #[error(
729        "The schema has a type named \"{expected_name}\" but it is not set as the query root type (\"{found_name}\" is instead): this is not supported by federation. If a root type does not use its default name, there should be no other type with that default name."
730    )]
731    RootQueryUsed {
732        expected_name: Name,
733        found_name: Name,
734    },
735    #[error(
736        "The schema has a type named \"{expected_name}\" but it is not set as the mutation root type (\"{found_name}\" is instead): this is not supported by federation. If a root type does not use its default name, there should be no other type with that default name."
737    )]
738    RootMutationUsed {
739        expected_name: Name,
740        found_name: Name,
741    },
742    #[error(
743        "The schema has a type named \"{expected_name}\" but it is not set as the subscription root type (\"{found_name}\" is instead): this is not supported by federation. If a root type does not use its default name, there should be no other type with that default name."
744    )]
745    RootSubscriptionUsed {
746        expected_name: Name,
747        found_name: Name,
748    },
749    #[error("{message}")]
750    InvalidSubgraphName { message: String },
751    #[error("{message}")]
752    NoQueries { message: String },
753    #[error("{message}")]
754    InterfaceFieldNoImplem { message: String },
755    #[error("{message}")]
756    ExternalTypeMismatch { message: String },
757    #[error("{message}")]
758    ExternalCollisionWithAnotherDirective { message: String },
759    #[error("{message}")]
760    ExternalArgumentMissing { message: String },
761    #[error("{message}")]
762    ExternalArgumentTypeMismatch { message: String },
763    #[error("{message}")]
764    ExternalArgumentDefaultMismatch { message: String },
765    #[error("{message}")]
766    ExternalOnInterface { message: String },
767    #[error("{message}")]
768    MergedDirectiveApplicationOnExternal { message: String },
769    #[error("{message}")]
770    FieldTypeMismatch { message: String },
771    #[error("{message}")]
772    FieldArgumentTypeMismatch { message: String },
773    #[error("{message}")]
774    InputFieldDefaultMismatch { message: String },
775    #[error("{message}")]
776    FieldArgumentDefaultMismatch { message: String },
777    #[error("{message}")]
778    ExtensionWithNoBase { message: String },
779    #[error("{message}")]
780    ExternalMissingOnBase { message: String },
781    #[error("{message}")]
782    InvalidFieldSharing { message: String },
783    #[error("{message}")]
784    InvalidShareableUsage { message: String },
785    #[error("{message}")]
786    InvalidLinkDirectiveUsage { message: String },
787    #[error("{message}")]
788    InvalidLinkIdentifier { message: String },
789    #[error("{message}")]
790    ReferencedInaccessible {
791        message: String,
792        links: InaccessibleCompositionLinks,
793    },
794    #[error("{message}")]
795    DefaultValueUsesInaccessible {
796        message: String,
797        links: InaccessibleCompositionLinks,
798    },
799    #[error("{message}")]
800    QueryRootTypeInaccessible {
801        message: String,
802        links: InaccessibleCompositionLinks,
803    },
804    #[error("{message}")]
805    RequiredInaccessible {
806        message: String,
807        links: InaccessibleCompositionLinks,
808    },
809    #[error("{message}")]
810    ImplementedByInaccessible {
811        message: String,
812        links: InaccessibleCompositionLinks,
813    },
814    #[error("{message}")]
815    DisallowedInaccessible {
816        message: String,
817        links: InaccessibleCompositionLinks,
818    },
819    #[error("{message}")]
820    OnlyInaccessibleChildren {
821        message: String,
822        links: InaccessibleCompositionLinks,
823    },
824    #[error("{message}")]
825    RequiredInputFieldMissingInSomeSubgraph { message: String },
826    #[error("{message}")]
827    RequiredArgumentMissingInSomeSubgraph { message: String },
828    #[error("{message}")]
829    EmptyMergedInputType { message: String },
830    #[error("{message}")]
831    EnumValueMismatch { message: String },
832    #[error("{message}")]
833    EmptyMergedEnumType { message: String },
834    #[error("{message}")]
835    ShareableHasMismatchedRuntimeTypes { message: String },
836    #[error("{message}")]
837    SatisfiabilityError { message: String },
838    #[error("{message}")]
839    OverrideFromSelfError { message: String },
840    #[error("{message}")]
841    OverrideSourceHasOverride { message: String },
842    #[error("{message}")]
843    OverrideCollisionWithAnotherDirective { message: String },
844    #[error("{message}")]
845    OverrideOnInterface { message: String },
846    #[error("{message}")]
847    UnsupportedFeature {
848        message: String,
849        kind: UnsupportedFeatureKind,
850    },
851    #[error("{message}")]
852    InvalidFederationSupergraph { message: String },
853    #[error("{message}")]
854    DownstreamServiceError { message: String },
855    #[error("{message}")]
856    DirectiveCompositionError { message: String },
857    #[error("{message}")]
858    InterfaceObjectUsageError { message: String },
859    #[error("{message}")]
860    InterfaceKeyNotOnImplementation { message: String },
861    #[error("{message}")]
862    InterfaceKeyMissingImplementationType { message: String },
863    #[error("@defer is not supported on subscriptions")]
864    DeferredSubscriptionUnsupported,
865    #[error("{message}")]
866    QueryPlanComplexityExceeded { message: String },
867    #[error("the caller requested cancellation")]
868    PlanningCancelled,
869    #[error("No plan was found when subgraphs were disabled")]
870    NoPlanFoundWithDisabledSubgraphs,
871    #[error("Context name \"{name}\" may not contain an underscore.")]
872    ContextNameContainsUnderscore { name: String },
873    #[error("Context name \"{name}\" is invalid. It should have only alphanumeric characters.")]
874    ContextNameInvalid { name: String },
875    #[error("{message}")]
876    ContextNotSet { message: String },
877    #[error("{message}")]
878    NoContextReferenced { message: String },
879    #[error("{message}")]
880    NoSelectionForContext { message: String },
881    #[error("{message}")]
882    ContextNoResolvableKey { message: String },
883    #[error("@cost cannot be applied to interface \"{interface}.{field}\"")]
884    CostAppliedToInterfaceField { interface: Name, field: Name },
885    #[error("{message}")]
886    ContextSelectionInvalid { message: String },
887    #[error("{message}")]
888    ListSizeAppliedToNonList { message: String },
889    #[error("{message}")]
890    ListSizeInvalidAssumedSize { message: String },
891    #[error("{message}")]
892    ListSizeInvalidSlicingArgument { message: String },
893    #[error("{message}")]
894    ListSizeInvalidSizedField { message: String },
895    #[error("{message}")]
896    InvalidTagName { message: String },
897    /// `@cacheTag` directive validation errors (subgraph)
898    #[error("cacheTag format is invalid: {message}")]
899    CacheTagInvalidFormat { message: String },
900    #[error(
901        "error on field \"{field_name}\" on type \"{type_name}\": cacheTag can only apply on root fields or entity types"
902    )]
903    CacheTagAppliedToNonRootField { type_name: Name, field_name: Name },
904    #[error("cacheTag applied on root fields can only reference arguments in format using $args")]
905    CacheTagInvalidFormatArgumentOnRootField,
906    #[error("cacheTag applied on types can only reference arguments in format using $key")]
907    CacheTagInvalidFormatArgumentOnEntity { type_name: Name, format: String },
908    #[error(
909        "Object \"{0}\" is not an entity. cacheTag can only apply on resolvable entities, object containing at least 1 @key directive and resolvable"
910    )]
911    CacheTagEntityNotResolvable(Name),
912    #[error("{message}")]
913    QueryRootMissing { message: String },
914    #[error(
915        "Invalid use of @{directive_name} on {kind} \"{coordinate}\": @{directive_name} cannot be applied on interfaces, interface fields and interface objects"
916    )]
917    AuthRequirementsAppliedOnInterface {
918        directive_name: String,
919        kind: String,
920        coordinate: String,
921    },
922    #[error("{message}")]
923    MissingTransitiveAuthRequirements { message: String },
924}
925
926impl SingleFederationError {
927    pub fn code(&self) -> ErrorCode {
928        match self {
929            SingleFederationError::Internal { .. } => ErrorCode::Internal,
930            SingleFederationError::InternalRebaseError { .. } => ErrorCode::Internal,
931            SingleFederationError::InternalUnmergeableFields { .. } => ErrorCode::Internal,
932            SingleFederationError::InvalidGraphQL { .. }
933            | SingleFederationError::InvalidGraphQLName(_) => ErrorCode::InvalidGraphQL,
934            SingleFederationError::InvalidSubgraph { .. } => ErrorCode::InvalidGraphQL,
935            // Technically it's not invalid graphql, but it is invalid syntax inside graphql...
936            SingleFederationError::FromContextParseError { .. } => ErrorCode::InvalidGraphQL,
937            // TODO(@goto-bus-stop): this should have a different error code: it's not invalid,
938            // just unsupported due to internal limitations.
939            SingleFederationError::UnsupportedSpreadDirective { .. } => ErrorCode::InvalidGraphQL,
940            // TODO(@goto-bus-stop): this should have a different error code: it's not the graphql
941            // that's invalid, but the operation name
942            SingleFederationError::UnknownOperation => ErrorCode::InvalidGraphQL,
943            SingleFederationError::OperationNameNotProvided => ErrorCode::InvalidGraphQL,
944            SingleFederationError::DirectiveDefinitionInvalid { .. } => {
945                ErrorCode::DirectiveDefinitionInvalid
946            }
947            SingleFederationError::TypeDefinitionInvalid { .. } => ErrorCode::TypeDefinitionInvalid,
948            SingleFederationError::UnsupportedFederationDirective { .. } => {
949                ErrorCode::UnsupportedFederationDirective
950            }
951            SingleFederationError::UnsupportedFederationVersion { .. } => {
952                ErrorCode::UnsupportedFederationVersion
953            }
954            SingleFederationError::UnsupportedLinkedFeature { .. } => {
955                ErrorCode::UnsupportedLinkedFeature
956            }
957            SingleFederationError::UnknownFederationLinkVersion { .. } => {
958                ErrorCode::UnknownFederationLinkVersion
959            }
960            SingleFederationError::UnknownLinkVersion { .. } => ErrorCode::UnknownLinkVersion,
961            SingleFederationError::KeyFieldsHasArgs { .. } => ErrorCode::KeyFieldsHasArgs,
962            SingleFederationError::ProvidesFieldsHasArgs { .. } => ErrorCode::ProvidesFieldsHasArgs,
963            SingleFederationError::ProvidesFieldsMissingExternal { .. } => {
964                ErrorCode::ProvidesFieldsMissingExternal
965            }
966            SingleFederationError::RequiresFieldsMissingExternal { .. } => {
967                ErrorCode::RequiresFieldsMissingExternal
968            }
969            SingleFederationError::KeyUnsupportedOnInterface { .. } => {
970                ErrorCode::KeyUnsupportedOnInterface
971            }
972            SingleFederationError::ProvidesUnsupportedOnInterface { .. } => {
973                ErrorCode::ProvidesUnsupportedOnInterface
974            }
975            SingleFederationError::RequiresUnsupportedOnInterface { .. } => {
976                ErrorCode::RequiresUnsupportedOnInterface
977            }
978            SingleFederationError::KeyHasDirectiveInFieldsArg { .. } => {
979                ErrorCode::KeyDirectiveInFieldsArgs
980            }
981            SingleFederationError::ProvidesHasDirectiveInFieldsArg { .. } => {
982                ErrorCode::ProvidesDirectiveInFieldsArgs
983            }
984            SingleFederationError::RequiresHasDirectiveInFieldsArg { .. } => {
985                ErrorCode::RequiresDirectiveInFieldsArgs
986            }
987            SingleFederationError::ExternalUnused { .. } => ErrorCode::ExternalUnused,
988            SingleFederationError::TypeWithOnlyUnusedExternal { .. } => {
989                ErrorCode::TypeWithOnlyUnusedExternal
990            }
991            SingleFederationError::ProvidesOnNonObjectField { .. } => {
992                ErrorCode::ProvidesOnNonObjectField
993            }
994            SingleFederationError::KeyInvalidFieldsType { .. } => ErrorCode::KeyInvalidFieldsType,
995            SingleFederationError::ProvidesInvalidFieldsType { .. } => {
996                ErrorCode::ProvidesInvalidFieldsType
997            }
998            SingleFederationError::RequiresInvalidFieldsType { .. } => {
999                ErrorCode::RequiresInvalidFieldsType
1000            }
1001            SingleFederationError::KeyInvalidFields { .. } => ErrorCode::KeyInvalidFields,
1002            SingleFederationError::ProvidesInvalidFields { .. } => ErrorCode::ProvidesInvalidFields,
1003            SingleFederationError::RequiresInvalidFields { .. } => ErrorCode::RequiresInvalidFields,
1004            SingleFederationError::KeyFieldsSelectInvalidType { .. } => {
1005                ErrorCode::KeyFieldsSelectInvalidType
1006            }
1007            SingleFederationError::RootQueryUsed { .. } => ErrorCode::RootQueryUsed,
1008            SingleFederationError::RootMutationUsed { .. } => ErrorCode::RootMutationUsed,
1009            SingleFederationError::RootSubscriptionUsed { .. } => ErrorCode::RootSubscriptionUsed,
1010            SingleFederationError::InvalidSubgraphName { .. } => ErrorCode::InvalidSubgraphName,
1011            SingleFederationError::NoQueries { .. } => ErrorCode::NoQueries,
1012            SingleFederationError::InterfaceFieldNoImplem { .. } => {
1013                ErrorCode::InterfaceFieldNoImplem
1014            }
1015            SingleFederationError::ExternalTypeMismatch { .. } => ErrorCode::ExternalTypeMismatch,
1016            SingleFederationError::ExternalCollisionWithAnotherDirective { .. } => {
1017                ErrorCode::ExternalCollisionWithAnotherDirective
1018            }
1019            SingleFederationError::ExternalArgumentMissing { .. } => {
1020                ErrorCode::ExternalArgumentMissing
1021            }
1022            SingleFederationError::ExternalArgumentTypeMismatch { .. } => {
1023                ErrorCode::ExternalArgumentTypeMismatch
1024            }
1025            SingleFederationError::ExternalArgumentDefaultMismatch { .. } => {
1026                ErrorCode::ExternalArgumentDefaultMismatch
1027            }
1028            SingleFederationError::ExternalOnInterface { .. } => ErrorCode::ExternalOnInterface,
1029            SingleFederationError::MergedDirectiveApplicationOnExternal { .. } => {
1030                ErrorCode::MergedDirectiveApplicationOnExternal
1031            }
1032            SingleFederationError::FieldTypeMismatch { .. } => ErrorCode::FieldTypeMismatch,
1033            SingleFederationError::FieldArgumentTypeMismatch { .. } => {
1034                ErrorCode::FieldArgumentTypeMismatch
1035            }
1036            SingleFederationError::InputFieldDefaultMismatch { .. } => {
1037                ErrorCode::InputFieldDefaultMismatch
1038            }
1039            SingleFederationError::FieldArgumentDefaultMismatch { .. } => {
1040                ErrorCode::FieldArgumentDefaultMismatch
1041            }
1042            SingleFederationError::ExtensionWithNoBase { .. } => ErrorCode::ExtensionWithNoBase,
1043            SingleFederationError::ExternalMissingOnBase { .. } => ErrorCode::ExternalMissingOnBase,
1044            SingleFederationError::InvalidFieldSharing { .. } => ErrorCode::InvalidFieldSharing,
1045            SingleFederationError::InvalidShareableUsage { .. } => ErrorCode::InvalidShareableUsage,
1046            SingleFederationError::InvalidLinkDirectiveUsage { .. } => {
1047                ErrorCode::InvalidLinkDirectiveUsage
1048            }
1049            SingleFederationError::InvalidLinkIdentifier { .. } => ErrorCode::InvalidLinkIdentifier,
1050            SingleFederationError::ReferencedInaccessible { .. } => {
1051                ErrorCode::ReferencedInaccessible
1052            }
1053            SingleFederationError::DefaultValueUsesInaccessible { .. } => {
1054                ErrorCode::DefaultValueUsesInaccessible
1055            }
1056            SingleFederationError::QueryRootTypeInaccessible { .. } => {
1057                ErrorCode::QueryRootTypeInaccessible
1058            }
1059            SingleFederationError::RequiredInaccessible { .. } => ErrorCode::RequiredInaccessible,
1060            SingleFederationError::ImplementedByInaccessible { .. } => {
1061                ErrorCode::ImplementedByInaccessible
1062            }
1063            SingleFederationError::DisallowedInaccessible { .. } => {
1064                ErrorCode::DisallowedInaccessible
1065            }
1066            SingleFederationError::OnlyInaccessibleChildren { .. } => {
1067                ErrorCode::OnlyInaccessibleChildren
1068            }
1069            SingleFederationError::RequiredInputFieldMissingInSomeSubgraph { .. } => {
1070                ErrorCode::RequiredInputFieldMissingInSomeSubgraph
1071            }
1072            SingleFederationError::RequiredArgumentMissingInSomeSubgraph { .. } => {
1073                ErrorCode::RequiredArgumentMissingInSomeSubgraph
1074            }
1075            SingleFederationError::EmptyMergedInputType { .. } => ErrorCode::EmptyMergedInputType,
1076            SingleFederationError::EnumValueMismatch { .. } => ErrorCode::EnumValueMismatch,
1077            SingleFederationError::EmptyMergedEnumType { .. } => ErrorCode::EmptyMergedEnumType,
1078            SingleFederationError::ShareableHasMismatchedRuntimeTypes { .. } => {
1079                ErrorCode::ShareableHasMismatchedRuntimeTypes
1080            }
1081            SingleFederationError::SatisfiabilityError { .. } => ErrorCode::SatisfiabilityError,
1082            SingleFederationError::OverrideFromSelfError { .. } => ErrorCode::OverrideFromSelfError,
1083            SingleFederationError::OverrideSourceHasOverride { .. } => {
1084                ErrorCode::OverrideSourceHasOverride
1085            }
1086            SingleFederationError::OverrideCollisionWithAnotherDirective { .. } => {
1087                ErrorCode::OverrideCollisionWithAnotherDirective
1088            }
1089            SingleFederationError::OverrideOnInterface { .. } => ErrorCode::OverrideOnInterface,
1090            SingleFederationError::UnsupportedFeature { .. } => ErrorCode::UnsupportedFeature,
1091            SingleFederationError::InvalidFederationSupergraph { .. } => {
1092                ErrorCode::InvalidFederationSupergraph
1093            }
1094            SingleFederationError::DownstreamServiceError { .. } => {
1095                ErrorCode::DownstreamServiceError
1096            }
1097            SingleFederationError::DirectiveCompositionError { .. } => {
1098                ErrorCode::DirectiveCompositionError
1099            }
1100            SingleFederationError::InterfaceObjectUsageError { .. } => {
1101                ErrorCode::InterfaceObjectUsageError
1102            }
1103            SingleFederationError::InterfaceKeyNotOnImplementation { .. } => {
1104                ErrorCode::InterfaceKeyNotOnImplementation
1105            }
1106            SingleFederationError::InterfaceKeyMissingImplementationType { .. } => {
1107                ErrorCode::InterfaceKeyMissingImplementationType
1108            }
1109            SingleFederationError::DeferredSubscriptionUnsupported => ErrorCode::Internal,
1110            SingleFederationError::QueryPlanComplexityExceeded { .. } => {
1111                ErrorCode::QueryPlanComplexityExceededError
1112            }
1113            SingleFederationError::PlanningCancelled => ErrorCode::Internal,
1114            SingleFederationError::NoPlanFoundWithDisabledSubgraphs => {
1115                ErrorCode::NoPlanFoundWithDisabledSubgraphs
1116            }
1117            SingleFederationError::ContextNameContainsUnderscore { .. } => {
1118                ErrorCode::ContextNameContainsUnderscore
1119            }
1120            SingleFederationError::ContextNameInvalid { .. } => ErrorCode::ContextNameInvalid,
1121            SingleFederationError::ContextNotSet { .. } => ErrorCode::ContextNotSet,
1122            SingleFederationError::NoContextReferenced { .. } => ErrorCode::NoContextReferenced,
1123            SingleFederationError::NoSelectionForContext { .. } => ErrorCode::NoSelectionForContext,
1124            SingleFederationError::ContextNoResolvableKey { .. } => {
1125                ErrorCode::ContextNoResolvableKey
1126            }
1127            SingleFederationError::ContextSelectionInvalid { .. } => {
1128                ErrorCode::ContextSelectionInvalid
1129            }
1130            SingleFederationError::CostAppliedToInterfaceField { .. } => {
1131                ErrorCode::CostAppliedToInterfaceField
1132            }
1133            SingleFederationError::ListSizeAppliedToNonList { .. } => {
1134                ErrorCode::ListSizeAppliedToNonList
1135            }
1136            SingleFederationError::ListSizeInvalidAssumedSize { .. } => {
1137                ErrorCode::ListSizeInvalidAssumedSize
1138            }
1139            SingleFederationError::ListSizeInvalidSlicingArgument { .. } => {
1140                ErrorCode::ListSizeInvalidSlicingArgument
1141            }
1142            SingleFederationError::ListSizeInvalidSizedField { .. } => {
1143                ErrorCode::ListSizeInvalidSizedField
1144            }
1145            #[allow(unused)]
1146            SingleFederationError::InvalidFieldSharing { .. } => ErrorCode::InvalidFieldSharing,
1147            SingleFederationError::InvalidTagName { .. } => ErrorCode::InvalidTagName,
1148            SingleFederationError::CacheTagInvalidFormat { .. } => ErrorCode::CacheTagInvalidFormat,
1149            SingleFederationError::CacheTagAppliedToNonRootField { .. } => {
1150                ErrorCode::CacheTagAppliedToNonRootField
1151            }
1152            SingleFederationError::CacheTagInvalidFormatArgumentOnRootField => {
1153                ErrorCode::CacheTagInvalidFormatArgumentOnRootField
1154            }
1155            SingleFederationError::CacheTagInvalidFormatArgumentOnEntity { .. } => {
1156                ErrorCode::CacheTagInvalidFormatArgumentOnEntity
1157            }
1158            SingleFederationError::CacheTagEntityNotResolvable { .. } => {
1159                ErrorCode::CacheTagEntityNotResolvable
1160            }
1161            SingleFederationError::QueryRootMissing { .. } => ErrorCode::QueryRootMissing,
1162            SingleFederationError::AuthRequirementsAppliedOnInterface { .. } => {
1163                ErrorCode::AuthRequirementsAppliedOnInterface
1164            }
1165            SingleFederationError::MissingTransitiveAuthRequirements { .. } => {
1166                ErrorCode::MissingTransitiveAuthRequirements
1167            }
1168        }
1169    }
1170
1171    pub fn code_string(&self) -> String {
1172        self.code().definition().code().to_string()
1173    }
1174
1175    pub(crate) fn root_already_used(
1176        operation_type: OperationType,
1177        expected_name: Name,
1178        found_name: Name,
1179    ) -> Self {
1180        match operation_type {
1181            OperationType::Query => Self::RootQueryUsed {
1182                expected_name,
1183                found_name,
1184            },
1185            OperationType::Mutation => Self::RootMutationUsed {
1186                expected_name,
1187                found_name,
1188            },
1189            OperationType::Subscription => Self::RootSubscriptionUsed {
1190                expected_name,
1191                found_name,
1192            },
1193        }
1194    }
1195}
1196
1197impl From<InvalidNameError> for FederationError {
1198    fn from(err: InvalidNameError) -> Self {
1199        SingleFederationError::from(err).into()
1200    }
1201}
1202
1203impl From<FederationSpecError> for FederationError {
1204    fn from(err: FederationSpecError) -> Self {
1205        // TODO: When we get around to finishing the composition port, we should really switch it to
1206        // using FederationError instead of FederationSpecError.
1207        let message = err.to_string();
1208        match err {
1209            FederationSpecError::UnsupportedVersionError { .. } => {
1210                SingleFederationError::UnsupportedFederationVersion { message }.into()
1211            }
1212            FederationSpecError::UnsupportedFederationDirective { .. } => {
1213                SingleFederationError::UnsupportedFederationDirective { message }.into()
1214            }
1215            FederationSpecError::InvalidGraphQLName(message) => message.into(),
1216        }
1217    }
1218}
1219
1220#[derive(Debug, Clone, thiserror::Error, Default)]
1221pub struct MultipleFederationErrors {
1222    pub(crate) errors: Vec<SingleFederationError>,
1223}
1224
1225impl MultipleFederationErrors {
1226    pub fn new() -> Self {
1227        Self { errors: vec![] }
1228    }
1229
1230    pub fn push(&mut self, error: FederationError) {
1231        match error {
1232            FederationError::SingleFederationError(error) => {
1233                self.errors.push(error);
1234            }
1235            FederationError::MultipleFederationErrors(errors) => {
1236                self.errors.extend(errors.errors);
1237            }
1238            FederationError::AggregateFederationError(errors) => {
1239                self.errors.extend(errors.causes);
1240            }
1241        }
1242    }
1243
1244    pub(crate) fn and_try(mut self, other: Result<(), FederationError>) -> Self {
1245        match other {
1246            Ok(_) => self,
1247            Err(e) => {
1248                self.push(e);
1249                self
1250            }
1251        }
1252    }
1253}
1254
1255impl Display for MultipleFederationErrors {
1256    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
1257        write!(f, "The following errors occurred:")?;
1258        for error in &self.errors {
1259            write!(f, "\n  - ")?;
1260            for c in error.to_string().chars() {
1261                if c == '\n' {
1262                    write!(f, "\n    ")?;
1263                } else {
1264                    f.write_char(c)?;
1265                }
1266            }
1267        }
1268        Ok(())
1269    }
1270}
1271
1272impl FromIterator<SingleFederationError> for MultipleFederationErrors {
1273    fn from_iter<T: IntoIterator<Item = SingleFederationError>>(iter: T) -> Self {
1274        Self {
1275            errors: iter.into_iter().collect(),
1276        }
1277    }
1278}
1279
1280#[derive(Debug, Clone, thiserror::Error)]
1281pub struct AggregateFederationError {
1282    pub code: String,
1283    pub message: String,
1284    pub causes: Vec<SingleFederationError>,
1285}
1286
1287impl Display for AggregateFederationError {
1288    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
1289        write!(f, "[{}] {}\nCaused by:", self.code, self.message)?;
1290        for error in &self.causes {
1291            write!(f, "\n\n  - ")?;
1292            for c in error.to_string().chars() {
1293                if c == '\n' {
1294                    write!(f, "\n    ")?;
1295                } else {
1296                    f.write_char(c)?;
1297                }
1298            }
1299        }
1300        Ok(())
1301    }
1302}
1303
1304// PORT_NOTE: Often times, JS functions would either throw/return a GraphQLError, return a vector
1305// of GraphQLErrors, or take a vector of GraphQLErrors and group them together under an
1306// AggregateGraphQLError which itself would have a specific error message and code, and throw that.
1307// We represent all these cases with an enum, and delegate to the members.
1308#[derive(Clone, thiserror::Error)]
1309pub enum FederationError {
1310    #[error(transparent)]
1311    SingleFederationError(#[from] SingleFederationError),
1312    #[error(transparent)]
1313    MultipleFederationErrors(#[from] MultipleFederationErrors),
1314    #[error(transparent)]
1315    AggregateFederationError(#[from] AggregateFederationError),
1316}
1317
1318impl std::fmt::Debug for FederationError {
1319    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
1320        match self {
1321            Self::SingleFederationError(inner) => std::fmt::Debug::fmt(inner, f),
1322            Self::MultipleFederationErrors(inner) => std::fmt::Debug::fmt(inner, f),
1323            Self::AggregateFederationError(inner) => std::fmt::Debug::fmt(inner, f),
1324        }
1325    }
1326}
1327
1328impl From<DiagnosticList> for FederationError {
1329    fn from(value: DiagnosticList) -> Self {
1330        let errors: Vec<_> = value
1331            .iter()
1332            .map(|d| SingleFederationError::InvalidGraphQL {
1333                message: d.to_string(),
1334            })
1335            .collect();
1336        match errors.len().cmp(&1) {
1337            Ordering::Less => internal_error!("diagnostic list is unexpectedly empty"),
1338            Ordering::Equal => errors[0].clone().into(),
1339            Ordering::Greater => MultipleFederationErrors { errors }.into(),
1340        }
1341    }
1342}
1343
1344impl<T> From<WithErrors<T>> for FederationError {
1345    fn from(value: WithErrors<T>) -> Self {
1346        value.errors.into()
1347    }
1348}
1349
1350// Used for when we condition on a type `T: TryInto<U>`, but we have an infallible conversion of
1351// `T: Into<U>`. This allows us to unwrap the `Result<U, Infallible>` with `?`.
1352impl From<std::convert::Infallible> for FederationError {
1353    fn from(_: std::convert::Infallible) -> Self {
1354        unreachable!("Infallible should never be converted to FederationError")
1355    }
1356}
1357
1358impl FederationError {
1359    pub fn internal(message: impl Into<String>) -> Self {
1360        SingleFederationError::Internal {
1361            message: message.into(),
1362        }
1363        .into()
1364    }
1365
1366    pub fn merge(self, other: Self) -> Self {
1367        let mut result = MultipleFederationErrors::new();
1368        result.push(self);
1369        result.push(other);
1370        result.into()
1371    }
1372
1373    pub fn into_errors(self) -> Vec<SingleFederationError> {
1374        match self {
1375            FederationError::SingleFederationError(e) => vec![e],
1376            FederationError::MultipleFederationErrors(e) => e.errors,
1377            FederationError::AggregateFederationError(e) => e.causes,
1378        }
1379    }
1380
1381    pub fn errors(&self) -> Vec<&SingleFederationError> {
1382        match self {
1383            FederationError::SingleFederationError(e) => vec![e],
1384            FederationError::MultipleFederationErrors(e) => e.errors.iter().collect(),
1385            FederationError::AggregateFederationError(e) => e.causes.iter().collect(),
1386        }
1387    }
1388
1389    pub fn has_invalid_graphql_error(&self) -> bool {
1390        self.errors()
1391            .into_iter()
1392            .any(|e| matches!(e, SingleFederationError::InvalidGraphQL { .. }))
1393    }
1394}
1395
1396// Similar to `multi_try` crate, but with `FederationError` instead of `Vec<E>`.
1397pub trait MultiTry<U> {
1398    type Output;
1399
1400    fn and_try(self, other: Result<U, FederationError>) -> Self::Output;
1401}
1402
1403impl<U> MultiTry<U> for Result<(), FederationError> {
1404    type Output = Result<U, FederationError>;
1405
1406    fn and_try(self, other: Result<U, FederationError>) -> Result<U, FederationError> {
1407        match (self, other) {
1408            (Ok(_a), Ok(b)) => Ok(b),
1409            (Ok(_a), Err(b)) => Err(b),
1410            (Err(a), Ok(_b)) => Err(a),
1411            (Err(a), Err(b)) => Err(a.merge(b)),
1412        }
1413    }
1414}
1415
1416pub trait MultiTryAll: Sized + Iterator {
1417    /// Apply `predicate` on all elements of the iterator, collecting all errors (if any).
1418    /// - Returns Ok(()), if all elements are Ok.
1419    /// - Otherwise, returns a FederationError with all errors.
1420    /// - Note: Not to be confused with `try_for_each`, which stops on the first error.
1421    fn try_for_all<F>(self, mut predicate: F) -> Result<(), FederationError>
1422    where
1423        F: FnMut(Self::Item) -> Result<(), FederationError>,
1424    {
1425        let mut errors = MultipleFederationErrors::new();
1426        for item in self {
1427            match predicate(item) {
1428                Ok(()) => {}
1429                Err(e) => errors.push(e),
1430            }
1431        }
1432        errors.into_result()
1433    }
1434}
1435
1436impl<I: Iterator> MultiTryAll for I {}
1437
1438impl MultipleFederationErrors {
1439    /// Converts into `Result<(), FederationError>`.
1440    /// - The return value can be either Ok, Err with a SingleFederationError or MultipleFederationErrors,
1441    ///   depending on the number of errors in the input.
1442    pub fn into_result(self) -> Result<(), FederationError> {
1443        match self.errors.len().cmp(&1) {
1444            Ordering::Less => Ok(()),
1445            Ordering::Equal => Err(self.errors[0].clone().into()),
1446            Ordering::Greater => Err(self.into()),
1447        }
1448    }
1449}
1450
1451// We didn't track errors addition precisely pre-2.0 and tracking it now has an unclear ROI, so we
1452// just mark all the error code that predates 2.0 as 0.x.
1453const FED1_CODE: &str = "0.x";
1454
1455#[derive(Debug, Clone)]
1456pub struct ErrorCodeMetadata {
1457    pub added_in: &'static str,
1458    pub replaces: &'static [&'static str],
1459}
1460
1461#[derive(Debug)]
1462pub struct ErrorCodeDefinition {
1463    code: String,
1464    // PORT_NOTE: Known as "description" in the JS code. The name was changed to distinguish it from
1465    // Error.description().
1466    doc_description: String,
1467    metadata: ErrorCodeMetadata,
1468}
1469
1470impl ErrorCodeDefinition {
1471    fn new(code: String, doc_description: String, metadata: Option<ErrorCodeMetadata>) -> Self {
1472        Self {
1473            code,
1474            doc_description,
1475            metadata: metadata.unwrap_or_else(|| DEFAULT_METADATA.clone()),
1476        }
1477    }
1478
1479    pub fn code(&self) -> &str {
1480        &self.code
1481    }
1482
1483    pub fn doc_description(&self) -> &str {
1484        &self.doc_description
1485    }
1486
1487    pub fn metadata(&self) -> &ErrorCodeMetadata {
1488        &self.metadata
1489    }
1490}
1491
1492/*
1493 * Most codes currently originate from the initial fed 2 release so we use this for convenience.
1494 * This can be changed later, inline versions everywhere, if that becomes irrelevant.
1495 */
1496static DEFAULT_METADATA: ErrorCodeMetadata = ErrorCodeMetadata {
1497    added_in: "2.0.0",
1498    replaces: &[],
1499};
1500
1501struct ErrorCodeCategory<TElement: Clone + Into<String>> {
1502    // Fn(element: TElement) -> String
1503    extract_code: Box<dyn 'static + Send + Sync + Fn(TElement) -> String>,
1504    // Fn(element: TElement) -> String
1505    make_doc_description: Box<dyn 'static + Send + Sync + Fn(TElement) -> String>,
1506    metadata: ErrorCodeMetadata,
1507}
1508
1509impl<TElement: Clone + Into<String>> ErrorCodeCategory<TElement> {
1510    fn new(
1511        extract_code: Box<dyn 'static + Send + Sync + Fn(TElement) -> String>,
1512        make_doc_description: Box<dyn 'static + Send + Sync + Fn(TElement) -> String>,
1513        metadata: Option<ErrorCodeMetadata>,
1514    ) -> Self {
1515        Self {
1516            extract_code,
1517            make_doc_description,
1518            metadata: metadata.unwrap_or_else(|| DEFAULT_METADATA.clone()),
1519        }
1520    }
1521
1522    // PORT_NOTE: The Typescript type in the JS code only has get(), but I also added createCode()
1523    // here since it's used in the return type of makeErrorCodeCategory().
1524    fn create_code(&self, element: TElement) -> ErrorCodeDefinition {
1525        ErrorCodeDefinition::new(
1526            (self.extract_code)(element.clone()),
1527            (self.make_doc_description)(element),
1528            Some(self.metadata.clone()),
1529        )
1530    }
1531}
1532
1533impl ErrorCodeCategory<String> {
1534    fn new_federation_directive(
1535        code_suffix: String,
1536        make_doc_description: Box<dyn 'static + Send + Sync + Fn(String) -> String>,
1537        metadata: Option<ErrorCodeMetadata>,
1538    ) -> Self {
1539        Self::new(
1540            Box::new(move |element: String| format!("{}_{}", element.to_uppercase(), code_suffix)),
1541            make_doc_description,
1542            metadata,
1543        )
1544    }
1545}
1546
1547static INVALID_GRAPHQL: LazyLock<ErrorCodeDefinition> = LazyLock::new(|| {
1548    ErrorCodeDefinition::new(
1549        "INVALID_GRAPHQL".to_owned(),
1550        "A schema is invalid GraphQL: it violates one of the rule of the specification.".to_owned(),
1551        None,
1552    )
1553});
1554static DIRECTIVE_DEFINITION_INVALID: LazyLock<ErrorCodeDefinition> = LazyLock::new(|| {
1555    ErrorCodeDefinition::new(
1556        "DIRECTIVE_DEFINITION_INVALID".to_owned(),
1557        "A built-in or federation directive has an invalid definition in the schema.".to_owned(),
1558        Some(ErrorCodeMetadata {
1559            replaces: &["TAG_DEFINITION_INVALID"],
1560            ..DEFAULT_METADATA.clone()
1561        }),
1562    )
1563});
1564
1565static TYPE_DEFINITION_INVALID: LazyLock<ErrorCodeDefinition> = LazyLock::new(|| {
1566    ErrorCodeDefinition::new(
1567        "TYPE_DEFINITION_INVALID".to_owned(),
1568        "A built-in or federation type has an invalid definition in the schema.".to_owned(),
1569        None,
1570    )
1571});
1572
1573static UNSUPPORTED_LINKED_FEATURE: LazyLock<ErrorCodeDefinition> = LazyLock::new(|| {
1574    ErrorCodeDefinition::new(
1575        "UNSUPPORTED_LINKED_FEATURE".to_owned(),
1576        "Indicates that a feature used in a @link is either unsupported or is used with unsupported options.".to_owned(),
1577        None,
1578    )
1579});
1580
1581static UNKNOWN_FEDERATION_LINK_VERSION: LazyLock<ErrorCodeDefinition> = LazyLock::new(|| {
1582    ErrorCodeDefinition::new(
1583        "UNKNOWN_FEDERATION_LINK_VERSION".to_owned(),
1584        "The version of federation in a @link directive on the schema is unknown.".to_owned(),
1585        None,
1586    )
1587});
1588
1589static UNKNOWN_LINK_VERSION: LazyLock<ErrorCodeDefinition> = LazyLock::new(|| {
1590    ErrorCodeDefinition::new(
1591        "UNKNOWN_LINK_VERSION".to_owned(),
1592        "The version of @link set on the schema is unknown.".to_owned(),
1593        Some(ErrorCodeMetadata {
1594            added_in: "2.1.0",
1595            replaces: &[],
1596        }),
1597    )
1598});
1599
1600static FIELDS_HAS_ARGS: LazyLock<ErrorCodeCategory<String>> = LazyLock::new(|| {
1601    ErrorCodeCategory::new_federation_directive(
1602        "FIELDS_HAS_ARGS".to_owned(),
1603        Box::new(|directive| {
1604            format!(
1605                "The `fields` argument of a `@{directive}` directive includes a field defined with arguments (which is not currently supported)."
1606            )
1607        }),
1608        None,
1609    )
1610});
1611
1612static KEY_FIELDS_HAS_ARGS: LazyLock<ErrorCodeDefinition> =
1613    LazyLock::new(|| FIELDS_HAS_ARGS.create_code("key".to_owned()));
1614
1615static PROVIDES_FIELDS_HAS_ARGS: LazyLock<ErrorCodeDefinition> =
1616    LazyLock::new(|| FIELDS_HAS_ARGS.create_code("provides".to_owned()));
1617
1618static DIRECTIVE_FIELDS_MISSING_EXTERNAL: LazyLock<ErrorCodeCategory<String>> = LazyLock::new(
1619    || {
1620        ErrorCodeCategory::new_federation_directive(
1621            "FIELDS_MISSING_EXTERNAL".to_owned(),
1622            Box::new(|directive| {
1623                format!(
1624                    "The `fields` argument of a `@{directive}` directive includes a field that is not marked as `@external`."
1625                )
1626            }),
1627            Some(ErrorCodeMetadata {
1628                added_in: FED1_CODE,
1629                replaces: &[],
1630            }),
1631        )
1632    },
1633);
1634
1635static PROVIDES_FIELDS_MISSING_EXTERNAL: LazyLock<ErrorCodeDefinition> =
1636    LazyLock::new(|| DIRECTIVE_FIELDS_MISSING_EXTERNAL.create_code("provides".to_owned()));
1637static REQUIRES_FIELDS_MISSING_EXTERNAL: LazyLock<ErrorCodeDefinition> =
1638    LazyLock::new(|| DIRECTIVE_FIELDS_MISSING_EXTERNAL.create_code("requires".to_owned()));
1639
1640static DIRECTIVE_UNSUPPORTED_ON_INTERFACE: LazyLock<ErrorCodeCategory<String>> =
1641    LazyLock::new(|| {
1642        ErrorCodeCategory::new_federation_directive(
1643            "UNSUPPORTED_ON_INTERFACE".to_owned(),
1644            Box::new(|directive| {
1645                let suffix = if directive == "key" {
1646                    "only supported when @linking to federation 2.3+"
1647                } else {
1648                    "not (yet) supported"
1649                };
1650                format!("A `@{directive}` directive is used on an interface, which is {suffix}.")
1651            }),
1652            None,
1653        )
1654    });
1655
1656static KEY_UNSUPPORTED_ON_INTERFACE: LazyLock<ErrorCodeDefinition> =
1657    LazyLock::new(|| DIRECTIVE_UNSUPPORTED_ON_INTERFACE.create_code("key".to_owned()));
1658static PROVIDES_UNSUPPORTED_ON_INTERFACE: LazyLock<ErrorCodeDefinition> =
1659    LazyLock::new(|| DIRECTIVE_UNSUPPORTED_ON_INTERFACE.create_code("provides".to_owned()));
1660static REQUIRES_UNSUPPORTED_ON_INTERFACE: LazyLock<ErrorCodeDefinition> =
1661    LazyLock::new(|| DIRECTIVE_UNSUPPORTED_ON_INTERFACE.create_code("requires".to_owned()));
1662
1663static DIRECTIVE_IN_FIELDS_ARG: LazyLock<ErrorCodeCategory<String>> = LazyLock::new(|| {
1664    ErrorCodeCategory::new_federation_directive(
1665        "DIRECTIVE_IN_FIELDS_ARG".to_owned(),
1666        Box::new(|directive| {
1667            format!(
1668                "The `fields` argument of a `@{directive}` directive includes some directive applications. This is not supported"
1669            )
1670        }),
1671        Some(ErrorCodeMetadata {
1672            added_in: "2.1.0",
1673            replaces: &[],
1674        }),
1675    )
1676});
1677
1678static KEY_DIRECTIVE_IN_FIELDS_ARGS: LazyLock<ErrorCodeDefinition> =
1679    LazyLock::new(|| DIRECTIVE_IN_FIELDS_ARG.create_code("key".to_owned()));
1680static PROVIDES_DIRECTIVE_IN_FIELDS_ARGS: LazyLock<ErrorCodeDefinition> =
1681    LazyLock::new(|| DIRECTIVE_IN_FIELDS_ARG.create_code("provides".to_owned()));
1682static REQUIRES_DIRECTIVE_IN_FIELDS_ARGS: LazyLock<ErrorCodeDefinition> =
1683    LazyLock::new(|| DIRECTIVE_IN_FIELDS_ARG.create_code("requires".to_owned()));
1684
1685static EXTERNAL_UNUSED: LazyLock<ErrorCodeDefinition> = LazyLock::new(|| {
1686    ErrorCodeDefinition::new(
1687        "EXTERNAL_UNUSED".to_owned(),
1688        "An `@external` field is not being used by any instance of `@key`, `@requires`, `@provides` or to satisfy an interface implementation.".to_owned(),
1689        Some(ErrorCodeMetadata {
1690            added_in: FED1_CODE,
1691            replaces: &[],
1692        }),
1693)
1694});
1695
1696static TYPE_WITH_ONLY_UNUSED_EXTERNAL: LazyLock<ErrorCodeDefinition> = LazyLock::new(|| {
1697    ErrorCodeDefinition::new(
1698        "TYPE_WITH_ONLY_UNUSED_EXTERNAL".to_owned(),
1699        [
1700            "A federation 1 schema has a composite type comprised only of unused external fields.".to_owned(),
1701            format!("Note that this error can _only_ be raised for federation 1 schema as federation 2 schema do not allow unused external fields (and errors with code {} will be raised in that case).", EXTERNAL_UNUSED.code),
1702            "But when federation 1 schema are automatically migrated to federation 2 ones, unused external fields are automatically removed, and in rare case this can leave a type empty. If that happens, an error with this code will be raised".to_owned()
1703        ].join(" "),
1704        None,
1705)
1706});
1707
1708static PROVIDES_ON_NON_OBJECT_FIELD: LazyLock<ErrorCodeDefinition> = LazyLock::new(|| {
1709    ErrorCodeDefinition::new(
1710        "PROVIDES_ON_NON_OBJECT_FIELD".to_owned(),
1711        "A `@provides` directive is used to mark a field whose base type is not an object type."
1712            .to_owned(),
1713        None,
1714    )
1715});
1716
1717static DIRECTIVE_INVALID_FIELDS_TYPE: LazyLock<ErrorCodeCategory<String>> = LazyLock::new(|| {
1718    ErrorCodeCategory::new_federation_directive(
1719        "INVALID_FIELDS_TYPE".to_owned(),
1720        Box::new(|directive| {
1721            format!(
1722                "The value passed to the `fields` argument of a `@{directive}` directive is not a string."
1723            )
1724        }),
1725        None,
1726    )
1727});
1728
1729static KEY_INVALID_FIELDS_TYPE: LazyLock<ErrorCodeDefinition> =
1730    LazyLock::new(|| DIRECTIVE_INVALID_FIELDS_TYPE.create_code("key".to_owned()));
1731static PROVIDES_INVALID_FIELDS_TYPE: LazyLock<ErrorCodeDefinition> =
1732    LazyLock::new(|| DIRECTIVE_INVALID_FIELDS_TYPE.create_code("provides".to_owned()));
1733static REQUIRES_INVALID_FIELDS_TYPE: LazyLock<ErrorCodeDefinition> =
1734    LazyLock::new(|| DIRECTIVE_INVALID_FIELDS_TYPE.create_code("requires".to_owned()));
1735
1736static DIRECTIVE_INVALID_FIELDS: LazyLock<ErrorCodeCategory<String>> = LazyLock::new(|| {
1737    ErrorCodeCategory::new_federation_directive(
1738        "INVALID_FIELDS".to_owned(),
1739        Box::new(|directive| {
1740            format!(
1741                "The `fields` argument of a `@{directive}` directive is invalid (it has invalid syntax, includes unknown fields, ...)."
1742            )
1743        }),
1744        None,
1745    )
1746});
1747
1748static KEY_INVALID_FIELDS: LazyLock<ErrorCodeDefinition> =
1749    LazyLock::new(|| DIRECTIVE_INVALID_FIELDS.create_code("key".to_owned()));
1750static PROVIDES_INVALID_FIELDS: LazyLock<ErrorCodeDefinition> =
1751    LazyLock::new(|| DIRECTIVE_INVALID_FIELDS.create_code("provides".to_owned()));
1752static REQUIRES_INVALID_FIELDS: LazyLock<ErrorCodeDefinition> =
1753    LazyLock::new(|| DIRECTIVE_INVALID_FIELDS.create_code("requires".to_owned()));
1754
1755static KEY_FIELDS_SELECT_INVALID_TYPE: LazyLock<ErrorCodeDefinition> = LazyLock::new(|| {
1756    ErrorCodeDefinition::new(
1757        "KEY_FIELDS_SELECT_INVALID_TYPE".to_owned(),
1758        "The `fields` argument of `@key` directive includes a field whose type is a list, interface, or union type. Fields of these types cannot be part of a `@key`".to_owned(),
1759        Some(ErrorCodeMetadata {
1760            added_in: FED1_CODE,
1761            replaces: &[],
1762        }),
1763)
1764});
1765
1766static ROOT_TYPE_USED: LazyLock<ErrorCodeCategory<SchemaRootKind>> = LazyLock::new(|| {
1767    ErrorCodeCategory::new(
1768        Box::new(|element| {
1769            let kind: String = element.into();
1770            format!("ROOT_{}_USED", kind.to_uppercase())
1771        }),
1772        Box::new(|element| {
1773            let kind: String = element.into();
1774            format!(
1775                "A subgraph's schema defines a type with the name `{kind}`, while also specifying a _different_ type name as the root query object. This is not allowed."
1776            )
1777        }),
1778        Some(ErrorCodeMetadata {
1779            added_in: FED1_CODE,
1780            replaces: &[],
1781        }),
1782    )
1783});
1784
1785static ROOT_QUERY_USED: LazyLock<ErrorCodeDefinition> =
1786    LazyLock::new(|| ROOT_TYPE_USED.create_code(SchemaRootKind::Query));
1787static ROOT_MUTATION_USED: LazyLock<ErrorCodeDefinition> =
1788    LazyLock::new(|| ROOT_TYPE_USED.create_code(SchemaRootKind::Mutation));
1789static ROOT_SUBSCRIPTION_USED: LazyLock<ErrorCodeDefinition> =
1790    LazyLock::new(|| ROOT_TYPE_USED.create_code(SchemaRootKind::Subscription));
1791
1792static INVALID_SUBGRAPH_NAME: LazyLock<ErrorCodeDefinition> = LazyLock::new(|| {
1793    ErrorCodeDefinition::new(
1794        "INVALID_SUBGRAPH_NAME".to_owned(),
1795        "A subgraph name is invalid (subgraph names cannot be a single underscore (\"_\"))."
1796            .to_owned(),
1797        None,
1798    )
1799});
1800
1801static NO_QUERIES: LazyLock<ErrorCodeDefinition> = LazyLock::new(|| {
1802    ErrorCodeDefinition::new(
1803        "NO_QUERIES".to_owned(),
1804        "None of the composed subgraphs expose any query.".to_owned(),
1805        None,
1806    )
1807});
1808
1809static INTERFACE_FIELD_NO_IMPLEM: LazyLock<ErrorCodeDefinition> = LazyLock::new(|| {
1810    ErrorCodeDefinition::new(
1811        "INTERFACE_FIELD_NO_IMPLEM".to_owned(),
1812        "After subgraph merging, an implementation is missing a field of one of the interface it implements (which can happen for valid subgraphs).".to_owned(),
1813        None,
1814    )
1815});
1816
1817static TYPE_KIND_MISMATCH: LazyLock<ErrorCodeDefinition> = LazyLock::new(|| {
1818    ErrorCodeDefinition::new(
1819        "TYPE_KIND_MISMATCH".to_owned(),
1820        "A type has the same name in different subgraphs, but a different kind. For instance, one definition is an object type but another is an interface.".to_owned(),
1821        Some(ErrorCodeMetadata {
1822            replaces: &["VALUE_TYPE_KIND_MISMATCH", "EXTENSION_OF_WRONG_KIND", "ENUM_MISMATCH_TYPE"],
1823            ..DEFAULT_METADATA.clone()
1824        }),
1825    )
1826});
1827
1828static EXTERNAL_TYPE_MISMATCH: LazyLock<ErrorCodeDefinition> = LazyLock::new(|| {
1829    ErrorCodeDefinition::new(
1830        "EXTERNAL_TYPE_MISMATCH".to_owned(),
1831        "An `@external` field has a type that is incompatible with the declaration(s) of that field in other subgraphs.".to_owned(),
1832        Some(ErrorCodeMetadata {
1833            added_in: FED1_CODE,
1834            replaces: &[],
1835        }),
1836    )
1837});
1838
1839static EXTERNAL_COLLISION_WITH_ANOTHER_DIRECTIVE: LazyLock<ErrorCodeDefinition> =
1840    LazyLock::new(|| {
1841        ErrorCodeDefinition::new(
1842            "EXTERNAL_COLLISION_WITH_ANOTHER_DIRECTIVE".to_owned(),
1843            "The @external directive collides with other directives in some situations.".to_owned(),
1844            Some(ErrorCodeMetadata {
1845                added_in: "2.1.0",
1846                replaces: &[],
1847            }),
1848        )
1849    });
1850
1851static EXTERNAL_ARGUMENT_MISSING: LazyLock<ErrorCodeDefinition> = LazyLock::new(|| {
1852    ErrorCodeDefinition::new(
1853        "EXTERNAL_ARGUMENT_MISSING".to_owned(),
1854        "An `@external` field is missing some arguments present in the declaration(s) of that field in other subgraphs.".to_owned(),
1855        None,
1856    )
1857});
1858
1859static EXTERNAL_ARGUMENT_TYPE_MISMATCH: LazyLock<ErrorCodeDefinition> = LazyLock::new(|| {
1860    ErrorCodeDefinition::new(
1861        "EXTERNAL_ARGUMENT_TYPE_MISMATCH".to_owned(),
1862        "An `@external` field declares an argument with a type that is incompatible with the corresponding argument in the declaration(s) of that field in other subgraphs.".to_owned(),
1863        None,
1864    )
1865});
1866
1867static EXTERNAL_ARGUMENT_DEFAULT_MISMATCH: LazyLock<ErrorCodeDefinition> = LazyLock::new(|| {
1868    ErrorCodeDefinition::new(
1869        "EXTERNAL_ARGUMENT_DEFAULT_MISMATCH".to_owned(),
1870        "An `@external` field declares an argument with a default that is incompatible with the corresponding argument in the declaration(s) of that field in other subgraphs.".to_owned(),
1871        None,
1872    )
1873});
1874
1875static EXTERNAL_ON_INTERFACE: LazyLock<ErrorCodeDefinition> = LazyLock::new(|| {
1876    ErrorCodeDefinition::new(
1877        "EXTERNAL_ON_INTERFACE".to_owned(),
1878        "The field of an interface type is marked with `@external`: as external is about marking field not resolved by the subgraph and as interface field are not resolved (only implementations of those fields are), an \"external\" interface field is nonsensical".to_owned(),
1879        None,
1880    )
1881});
1882
1883static MERGED_DIRECTIVE_APPLICATION_ON_EXTERNAL: LazyLock<ErrorCodeDefinition> = LazyLock::new(
1884    || {
1885        ErrorCodeDefinition::new(
1886        "MERGED_DIRECTIVE_APPLICATION_ON_EXTERNAL".to_owned(),
1887        "In a subgraph, a field is both marked @external and has a merged directive applied to it".to_owned(),
1888        None,
1889    )
1890    },
1891);
1892
1893static FIELD_TYPE_MISMATCH: LazyLock<ErrorCodeDefinition> = LazyLock::new(|| {
1894    ErrorCodeDefinition::new(
1895        "FIELD_TYPE_MISMATCH".to_owned(),
1896        "A field has a type that is incompatible with other declarations of that field in other subgraphs.".to_owned(),
1897        Some(ErrorCodeMetadata {
1898            replaces: &["VALUE_TYPE_FIELD_TYPE_MISMATCH"],
1899            ..DEFAULT_METADATA.clone()
1900        }),
1901    )
1902});
1903
1904static FIELD_ARGUMENT_TYPE_MISMATCH: LazyLock<ErrorCodeDefinition> = LazyLock::new(|| {
1905    ErrorCodeDefinition::new(
1906        "FIELD_ARGUMENT_TYPE_MISMATCH".to_owned(),
1907        "An argument (of a field/directive) has a type that is incompatible with that of other declarations of that same argument in other subgraphs.".to_owned(),
1908        Some(ErrorCodeMetadata {
1909            replaces: &["VALUE_TYPE_INPUT_VALUE_MISMATCH"],
1910            ..DEFAULT_METADATA.clone()
1911        }),
1912    )
1913});
1914
1915static INPUT_FIELD_DEFAULT_MISMATCH: LazyLock<ErrorCodeDefinition> = LazyLock::new(|| {
1916    ErrorCodeDefinition::new(
1917        "INPUT_FIELD_DEFAULT_MISMATCH".to_owned(),
1918        "An input field has a default value that is incompatible with other declarations of that field in other subgraphs.".to_owned(),
1919        None,
1920    )
1921});
1922
1923static FIELD_ARGUMENT_DEFAULT_MISMATCH: LazyLock<ErrorCodeDefinition> = LazyLock::new(|| {
1924    ErrorCodeDefinition::new(
1925        "FIELD_ARGUMENT_DEFAULT_MISMATCH".to_owned(),
1926        "An argument (of a field/directive) has a default value that is incompatible with that of other declarations of that same argument in other subgraphs.".to_owned(),
1927        None,
1928    )
1929});
1930
1931static EXTENSION_WITH_NO_BASE: LazyLock<ErrorCodeDefinition> = LazyLock::new(|| {
1932    ErrorCodeDefinition::new(
1933        "EXTENSION_WITH_NO_BASE".to_owned(),
1934        "A subgraph is attempting to `extend` a type that is not originally defined in any known subgraph.".to_owned(),
1935        Some(ErrorCodeMetadata {
1936            added_in: FED1_CODE,
1937            replaces: &[],
1938        }),
1939    )
1940});
1941
1942static EXTERNAL_MISSING_ON_BASE: LazyLock<ErrorCodeDefinition> = LazyLock::new(|| {
1943    ErrorCodeDefinition::new(
1944        "EXTERNAL_MISSING_ON_BASE".to_owned(),
1945        "A field is marked as `@external` in a subgraph but with no non-external declaration in any other subgraph.".to_owned(),
1946        Some(ErrorCodeMetadata {
1947            added_in: FED1_CODE,
1948            replaces: &[],
1949        }),
1950    )
1951});
1952
1953static INVALID_FIELD_SHARING: LazyLock<ErrorCodeDefinition> = LazyLock::new(|| {
1954    ErrorCodeDefinition::new(
1955        "INVALID_FIELD_SHARING".to_owned(),
1956        "A field that is non-shareable in at least one subgraph is resolved by multiple subgraphs."
1957            .to_owned(),
1958        None,
1959    )
1960});
1961
1962static INVALID_SHAREABLE_USAGE: LazyLock<ErrorCodeDefinition> = LazyLock::new(|| {
1963    ErrorCodeDefinition::new(
1964        "INVALID_SHAREABLE_USAGE".to_owned(),
1965        "The `@shareable` federation directive is used in an invalid way.".to_owned(),
1966        Some(ErrorCodeMetadata {
1967            added_in: "2.1.2",
1968            replaces: &[],
1969        }),
1970    )
1971});
1972
1973static INVALID_LINK_DIRECTIVE_USAGE: LazyLock<ErrorCodeDefinition> = LazyLock::new(|| {
1974    ErrorCodeDefinition::new(
1975        "INVALID_LINK_DIRECTIVE_USAGE".to_owned(),
1976        "An application of the @link directive is invalid/does not respect the specification."
1977            .to_owned(),
1978        None,
1979    )
1980});
1981
1982static INVALID_LINK_IDENTIFIER: LazyLock<ErrorCodeDefinition> = LazyLock::new(|| {
1983    ErrorCodeDefinition::new(
1984        "INVALID_LINK_IDENTIFIER".to_owned(),
1985        "A url/version for a @link feature is invalid/does not respect the specification."
1986            .to_owned(),
1987        Some(ErrorCodeMetadata {
1988            added_in: "2.1.0",
1989            replaces: &[],
1990        }),
1991    )
1992});
1993
1994static LINK_IMPORT_NAME_MISMATCH: LazyLock<ErrorCodeDefinition> = LazyLock::new(|| {
1995    ErrorCodeDefinition::new(
1996        "LINK_IMPORT_NAME_MISMATCH".to_owned(),
1997        "The import name for a merged directive (as declared by the relevant `@link(import:)` argument) is inconsistent between subgraphs.".to_owned(),
1998        None,
1999    )
2000});
2001
2002static REFERENCED_INACCESSIBLE: LazyLock<ErrorCodeDefinition> = LazyLock::new(|| {
2003    ErrorCodeDefinition::new(
2004        "REFERENCED_INACCESSIBLE".to_owned(),
2005        "An element is marked as @inaccessible but is referenced by an element visible in the API schema.".to_owned(),
2006        None,
2007    )
2008});
2009
2010static DEFAULT_VALUE_USES_INACCESSIBLE: LazyLock<ErrorCodeDefinition> = LazyLock::new(|| {
2011    ErrorCodeDefinition::new(
2012        "DEFAULT_VALUE_USES_INACCESSIBLE".to_owned(),
2013        "An element is marked as @inaccessible but is used in the default value of an element visible in the API schema.".to_owned(),
2014        None,
2015    )
2016});
2017
2018static QUERY_ROOT_TYPE_INACCESSIBLE: LazyLock<ErrorCodeDefinition> = LazyLock::new(|| {
2019    ErrorCodeDefinition::new(
2020        "QUERY_ROOT_TYPE_INACCESSIBLE".to_owned(),
2021        "An element is marked as @inaccessible but is the query root type, which must be visible in the API schema.".to_owned(),
2022        None,
2023    )
2024});
2025
2026static REQUIRED_INACCESSIBLE: LazyLock<ErrorCodeDefinition> = LazyLock::new(|| {
2027    ErrorCodeDefinition::new(
2028        "REQUIRED_INACCESSIBLE".to_owned(),
2029        "An element is marked as @inaccessible but is required by an element visible in the API schema.".to_owned(),
2030        None,
2031    )
2032});
2033
2034static IMPLEMENTED_BY_INACCESSIBLE: LazyLock<ErrorCodeDefinition> = LazyLock::new(|| {
2035    ErrorCodeDefinition::new(
2036        "IMPLEMENTED_BY_INACCESSIBLE".to_owned(),
2037        "An element is marked as @inaccessible but implements an element visible in the API schema.".to_owned(),
2038        None,
2039    )
2040});
2041
2042static DISALLOWED_INACCESSIBLE: LazyLock<ErrorCodeDefinition> = LazyLock::new(|| {
2043    ErrorCodeDefinition::new(
2044        "DISALLOWED_INACCESSIBLE".to_owned(),
2045        "An element is marked as @inaccessible that is not allowed to be @inaccessible.".to_owned(),
2046        None,
2047    )
2048});
2049
2050static ONLY_INACCESSIBLE_CHILDREN: LazyLock<ErrorCodeDefinition> = LazyLock::new(|| {
2051    ErrorCodeDefinition::new(
2052        "ONLY_INACCESSIBLE_CHILDREN".to_owned(),
2053        "A type visible in the API schema has only @inaccessible children.".to_owned(),
2054        None,
2055    )
2056});
2057
2058static REQUIRED_INPUT_FIELD_MISSING_IN_SOME_SUBGRAPH: LazyLock<ErrorCodeDefinition> = LazyLock::new(
2059    || {
2060        ErrorCodeDefinition::new(
2061        "REQUIRED_INPUT_FIELD_MISSING_IN_SOME_SUBGRAPH".to_owned(),
2062        "A field of an input object type is mandatory in some subgraphs, but the field is not defined in all the subgraphs that define the input object type.".to_owned(),
2063        None,
2064    )
2065    },
2066);
2067
2068static REQUIRED_ARGUMENT_MISSING_IN_SOME_SUBGRAPH: LazyLock<ErrorCodeDefinition> = LazyLock::new(
2069    || {
2070        ErrorCodeDefinition::new(
2071        "REQUIRED_ARGUMENT_MISSING_IN_SOME_SUBGRAPH".to_owned(),
2072        "An argument of a field or directive definition is mandatory in some subgraphs, but the argument is not defined in all the subgraphs that define the field or directive definition.".to_owned(),
2073        None,
2074    )
2075    },
2076);
2077
2078static EMPTY_MERGED_INPUT_TYPE: LazyLock<ErrorCodeDefinition> = LazyLock::new(|| {
2079    ErrorCodeDefinition::new(
2080        "EMPTY_MERGED_INPUT_TYPE".to_owned(),
2081        "An input object type has no field common to all the subgraphs that define the type. Merging that type would result in an invalid empty input object type.".to_owned(),
2082        None,
2083    )
2084});
2085
2086static INPUT_FIELD_MERGE_FAILED: LazyLock<ErrorCodeDefinition> = LazyLock::new(|| {
2087    ErrorCodeDefinition::new(
2088        "INPUT_FIELD_MERGE_FAILED".to_owned(),
2089        "Failed to merge an input object field due to incompatible definitions across subgraphs."
2090            .to_owned(),
2091        None,
2092    )
2093});
2094
2095static ENUM_VALUE_MISMATCH: LazyLock<ErrorCodeDefinition> = LazyLock::new(|| {
2096    ErrorCodeDefinition::new(
2097        "ENUM_VALUE_MISMATCH".to_owned(),
2098        "An enum type that is used as both an input and output type has a value that is not defined in all the subgraphs that define the enum type.".to_owned(),
2099        None,
2100    )
2101});
2102
2103static EMPTY_MERGED_ENUM_TYPE: LazyLock<ErrorCodeDefinition> = LazyLock::new(|| {
2104    ErrorCodeDefinition::new(
2105        "EMPTY_MERGED_ENUM_TYPE".to_owned(),
2106        "An enum type has no value common to all the subgraphs that define the type. Merging that type would result in an invalid empty enum type.".to_owned(),
2107        None,
2108    )
2109});
2110
2111static SHAREABLE_HAS_MISMATCHED_RUNTIME_TYPES: LazyLock<ErrorCodeDefinition> = LazyLock::new(
2112    || {
2113        ErrorCodeDefinition::new(
2114        "SHAREABLE_HAS_MISMATCHED_RUNTIME_TYPES".to_owned(),
2115        "A shareable field return type has mismatched possible runtime types in the subgraphs in which the field is declared. As shared fields must resolve the same way in all subgraphs, this is almost surely a mistake.".to_owned(),
2116        None,
2117    )
2118    },
2119);
2120
2121static SATISFIABILITY_ERROR: LazyLock<ErrorCodeDefinition> = LazyLock::new(|| {
2122    ErrorCodeDefinition::new(
2123        "SATISFIABILITY_ERROR".to_owned(),
2124        "Subgraphs can be merged, but the resulting supergraph API would have queries that cannot be satisfied by those subgraphs.".to_owned(),
2125        None,
2126    )
2127});
2128
2129static MAX_VALIDATION_SUBGRAPH_PATHS_EXCEEDED: LazyLock<ErrorCodeDefinition> =
2130    LazyLock::new(|| {
2131        ErrorCodeDefinition::new(
2132            "MAX_VALIDATION_SUBGRAPH_PATHS_EXCEEDED".to_owned(),
2133            "The maximum number of validation subgraph paths has been exceeded.".to_owned(),
2134            Some(ErrorCodeMetadata {
2135                added_in: "2.8.0",
2136                replaces: &[],
2137            }),
2138        )
2139    });
2140
2141static OVERRIDE_FROM_SELF_ERROR: LazyLock<ErrorCodeDefinition> = LazyLock::new(|| {
2142    ErrorCodeDefinition::new(
2143        "OVERRIDE_FROM_SELF_ERROR".to_owned(),
2144        "Field with `@override` directive has \"from\" location that references its own subgraph."
2145            .to_owned(),
2146        None,
2147    )
2148});
2149
2150static OVERRIDE_SOURCE_HAS_OVERRIDE: LazyLock<ErrorCodeDefinition> = LazyLock::new(|| {
2151    ErrorCodeDefinition::new(
2152        "OVERRIDE_SOURCE_HAS_OVERRIDE".to_owned(),
2153        "Field which is overridden to another subgraph is also marked @override.".to_owned(),
2154        None,
2155    )
2156});
2157
2158static OVERRIDE_COLLISION_WITH_ANOTHER_DIRECTIVE: LazyLock<ErrorCodeDefinition> = LazyLock::new(
2159    || {
2160        ErrorCodeDefinition::new(
2161        "OVERRIDE_COLLISION_WITH_ANOTHER_DIRECTIVE".to_owned(),
2162        "The @override directive cannot be used on external fields, nor to override fields with either @external, @provides, or @requires.".to_owned(),
2163        None,
2164    )
2165    },
2166);
2167
2168static OVERRIDE_ON_INTERFACE: LazyLock<ErrorCodeDefinition> = LazyLock::new(|| {
2169    ErrorCodeDefinition::new(
2170        "OVERRIDE_ON_INTERFACE".to_owned(),
2171        "The @override directive cannot be used on the fields of an interface type.".to_owned(),
2172        Some(ErrorCodeMetadata {
2173            added_in: "2.3.0",
2174            replaces: &[],
2175        }),
2176    )
2177});
2178
2179static OVERRIDE_LABEL_INVALID: LazyLock<ErrorCodeDefinition> = LazyLock::new(|| {
2180    ErrorCodeDefinition::new(
2181        "OVERRIDE_LABEL_INVALID".to_owned(),
2182        r#"The @override directive `label` argument must match the pattern /^[a-zA-Z][a-zA-Z0-9_\-:./]*$/ or /^percent\((\d{1,2}(\.\d{1,8})?|100)\)$/"#.to_owned(),
2183        Some(ErrorCodeMetadata {
2184            added_in: "2.7.0",
2185            replaces: &[],
2186        }),
2187    )
2188});
2189
2190static UNSUPPORTED_FEATURE: LazyLock<ErrorCodeDefinition> = LazyLock::new(|| {
2191    ErrorCodeDefinition::new(
2192        "UNSUPPORTED_FEATURE".to_owned(),
2193        "Indicates an error due to feature currently unsupported by federation.".to_owned(),
2194        Some(ErrorCodeMetadata {
2195            added_in: "2.1.0",
2196            replaces: &[],
2197        }),
2198    )
2199});
2200
2201static INVALID_FEDERATION_SUPERGRAPH: LazyLock<ErrorCodeDefinition> = LazyLock::new(|| {
2202    ErrorCodeDefinition::new(
2203        "INVALID_FEDERATION_SUPERGRAPH".to_owned(),
2204        "Indicates that a schema provided for an Apollo Federation supergraph is not a valid supergraph schema.".to_owned(),
2205        Some(ErrorCodeMetadata {
2206            added_in: "2.1.0",
2207            replaces: &[],
2208        }),
2209    )
2210});
2211
2212static DOWNSTREAM_SERVICE_ERROR: LazyLock<ErrorCodeDefinition> = LazyLock::new(|| {
2213    ErrorCodeDefinition::new(
2214        "DOWNSTREAM_SERVICE_ERROR".to_owned(),
2215        "Indicates an error in a subgraph service query during query execution in a federated service.".to_owned(),
2216        Some(ErrorCodeMetadata {
2217            added_in: FED1_CODE,
2218            replaces: &[],
2219        }),
2220    )
2221});
2222
2223static DIRECTIVE_COMPOSITION_ERROR: LazyLock<ErrorCodeDefinition> = LazyLock::new(|| {
2224    ErrorCodeDefinition::new(
2225        "DIRECTIVE_COMPOSITION_ERROR".to_owned(),
2226        "Error when composing custom directives.".to_owned(),
2227        Some(ErrorCodeMetadata {
2228            added_in: "2.1.0",
2229            replaces: &[],
2230        }),
2231    )
2232});
2233
2234static INTERFACE_OBJECT_USAGE_ERROR: LazyLock<ErrorCodeDefinition> = LazyLock::new(|| {
2235    ErrorCodeDefinition::new(
2236        "INTERFACE_OBJECT_USAGE_ERROR".to_owned(),
2237        "Error in the usage of the @interfaceObject directive.".to_owned(),
2238        Some(ErrorCodeMetadata {
2239            added_in: "2.3.0",
2240            replaces: &[],
2241        }),
2242    )
2243});
2244
2245static INTERFACE_KEY_NOT_ON_IMPLEMENTATION: LazyLock<ErrorCodeDefinition> = LazyLock::new(|| {
2246    ErrorCodeDefinition::new(
2247        "INTERFACE_KEY_NOT_ON_IMPLEMENTATION".to_owned(),
2248        "A `@key` is defined on an interface type, but is not defined (or is not resolvable) on at least one of the interface implementations".to_owned(),
2249        Some(ErrorCodeMetadata {
2250            added_in: "2.3.0",
2251            replaces: &[],
2252        }),
2253    )
2254});
2255
2256static INTERFACE_KEY_MISSING_IMPLEMENTATION_TYPE: LazyLock<ErrorCodeDefinition> = LazyLock::new(
2257    || {
2258        ErrorCodeDefinition::new(
2259        "INTERFACE_KEY_MISSING_IMPLEMENTATION_TYPE".to_owned(),
2260        "A subgraph has a `@key` on an interface type, but that subgraph does not define an implementation (in the supergraph) of that interface".to_owned(),
2261        Some(ErrorCodeMetadata {
2262            added_in: "2.3.0",
2263            replaces: &[],
2264        }),
2265    )
2266    },
2267);
2268
2269static INTERNAL: LazyLock<ErrorCodeDefinition> = LazyLock::new(|| {
2270    ErrorCodeDefinition::new(
2271        "INTERNAL".to_owned(),
2272        "An internal federation error occured.".to_owned(),
2273        None,
2274    )
2275});
2276
2277static ERROR_CODE_MISSING: LazyLock<ErrorCodeDefinition> = LazyLock::new(|| {
2278    ErrorCodeDefinition::new(
2279        "ERROR_CODE_MISSING".to_owned(),
2280        "An internal federation error occurred when translating a federation error into an error code".to_owned(),
2281        None,
2282    )
2283});
2284
2285static UNSUPPORTED_FEDERATION_VERSION: LazyLock<ErrorCodeDefinition> = LazyLock::new(|| {
2286    ErrorCodeDefinition::new(
2287        "UNSUPPORTED_FEDERATION_VERSION".to_owned(),
2288        "Supergraphs composed with federation version 1 are not supported. Please recompose your supergraph with federation version 2 or greater".to_owned(),
2289        None,
2290    )
2291});
2292
2293static UNSUPPORTED_FEDERATION_DIRECTIVE: LazyLock<ErrorCodeDefinition> = LazyLock::new(|| {
2294    ErrorCodeDefinition::new(
2295        "UNSUPPORTED_FEDERATION_DIRECTIVE".to_owned(),
2296        "Indicates that the specified specification version is outside of supported range"
2297            .to_owned(),
2298        None,
2299    )
2300});
2301
2302static QUERY_PLAN_COMPLEXITY_EXCEEDED: LazyLock<ErrorCodeDefinition> = LazyLock::new(|| {
2303    ErrorCodeDefinition::new(
2304        "QUERY_PLAN_COMPLEXITY_EXCEEDED".to_owned(),
2305        "Indicates that provided query has too many possible ways to generate a plan and cannot be planned in a reasonable amount of time"
2306            .to_owned(),
2307        None,
2308    )
2309});
2310
2311static NO_PLAN_FOUND_WITH_DISABLED_SUBGRAPHS: LazyLock<ErrorCodeDefinition> = LazyLock::new(|| {
2312    ErrorCodeDefinition::new(
2313        "NO_PLAN_FOUND_WITH_DISABLED_SUBGRAPHS".to_owned(),
2314        "Indicates that the provided query could not be query planned due to subgraphs being disabled"
2315            .to_owned(),
2316        None,
2317    )
2318});
2319
2320static COST_APPLIED_TO_INTERFACE_FIELD: LazyLock<ErrorCodeDefinition> = LazyLock::new(|| {
2321    ErrorCodeDefinition::new(
2322        "COST_APPLIED_TO_INTERFACE_FIELD".to_owned(),
2323        "The `@cost` directive must be applied to concrete types".to_owned(),
2324        Some(ErrorCodeMetadata {
2325            added_in: "2.9.2",
2326            replaces: &[],
2327        }),
2328    )
2329});
2330
2331static LIST_SIZE_APPLIED_TO_NON_LIST: LazyLock<ErrorCodeDefinition> = LazyLock::new(|| {
2332    ErrorCodeDefinition::new(
2333        "LIST_SIZE_APPLIED_TO_NON_LIST".to_owned(),
2334        "The `@listSize` directive must be applied to list types".to_owned(),
2335        Some(ErrorCodeMetadata {
2336            added_in: "2.9.2",
2337            replaces: &[],
2338        }),
2339    )
2340});
2341
2342static LIST_SIZE_INVALID_ASSUMED_SIZE: LazyLock<ErrorCodeDefinition> = LazyLock::new(|| {
2343    ErrorCodeDefinition::new(
2344        "LIST_SIZE_INVALID_ASSUMED_SIZE".to_owned(),
2345        "The `@listSize` directive assumed size cannot be negative".to_owned(),
2346        Some(ErrorCodeMetadata {
2347            added_in: "2.9.2",
2348            replaces: &[],
2349        }),
2350    )
2351});
2352
2353static LIST_SIZE_INVALID_SLICING_ARGUMENT: LazyLock<ErrorCodeDefinition> = LazyLock::new(|| {
2354    ErrorCodeDefinition::new(
2355        "LIST_SIZE_INVALID_SLICING_ARGUMENT".to_owned(),
2356        "The `@listSize` directive must have existing integer slicing arguments".to_owned(),
2357        Some(ErrorCodeMetadata {
2358            added_in: "2.9.2",
2359            replaces: &[],
2360        }),
2361    )
2362});
2363
2364static LIST_SIZE_INVALID_SIZED_FIELD: LazyLock<ErrorCodeDefinition> = LazyLock::new(|| {
2365    ErrorCodeDefinition::new(
2366        "LIST_SIZE_INVALID_SIZED_FIELD".to_owned(),
2367        "The `@listSize` directive must reference existing list fields as sized fields".to_owned(),
2368        Some(ErrorCodeMetadata {
2369            added_in: "2.9.2",
2370            replaces: &[],
2371        }),
2372    )
2373});
2374
2375static CONTEXT_NAME_CONTAINS_UNDERSCORE: LazyLock<ErrorCodeDefinition> = LazyLock::new(|| {
2376    ErrorCodeDefinition::new(
2377        "CONTEXT_NAME_CONTAINS_UNDERSCORE".to_owned(),
2378        "Context name is invalid.".to_owned(),
2379        Some(ErrorCodeMetadata {
2380            added_in: "2.8.0",
2381            replaces: &[],
2382        }),
2383    )
2384});
2385
2386static CONTEXT_NAME_INVALID: LazyLock<ErrorCodeDefinition> = LazyLock::new(|| {
2387    ErrorCodeDefinition::new(
2388        "CONTEXT_NAME_INVALID".to_owned(),
2389        "Context name is invalid.".to_owned(),
2390        Some(ErrorCodeMetadata {
2391            added_in: "2.8.0",
2392            replaces: &[],
2393        }),
2394    )
2395});
2396
2397static CONTEXT_NOT_SET: LazyLock<ErrorCodeDefinition> = LazyLock::new(|| {
2398    ErrorCodeDefinition::new(
2399        "CONTEXT_NOT_SET".to_owned(),
2400        "Context is never set for context trying to be used".to_owned(),
2401        Some(ErrorCodeMetadata {
2402            added_in: "2.8.0",
2403            replaces: &[],
2404        }),
2405    )
2406});
2407
2408static NO_CONTEXT_REFERENCED: LazyLock<ErrorCodeDefinition> = LazyLock::new(|| {
2409    ErrorCodeDefinition::new(
2410        "NO_CONTEXT_REFERENCED".to_owned(),
2411        "Selection in @fromContext field argument does not reference a context".to_owned(),
2412        Some(ErrorCodeMetadata {
2413            added_in: "2.8.0",
2414            replaces: &[],
2415        }),
2416    )
2417});
2418
2419static NO_SELECTION_FOR_CONTEXT: LazyLock<ErrorCodeDefinition> = LazyLock::new(|| {
2420    ErrorCodeDefinition::new(
2421        "NO_SELECTION_FOR_CONTEXT".to_owned(),
2422        "field parameter in @fromContext must contain a selection set".to_owned(),
2423        Some(ErrorCodeMetadata {
2424            added_in: "2.8.0",
2425            replaces: &[],
2426        }),
2427    )
2428});
2429
2430static CONTEXT_NO_RESOLVABLE_KEY: LazyLock<ErrorCodeDefinition> = LazyLock::new(|| {
2431    ErrorCodeDefinition::new(
2432        "CONTEXT_NO_RESOLVABLE_KEY".to_owned(),
2433        "If an ObjectType uses a @fromContext, at least one of its keys must be resolvable"
2434            .to_owned(),
2435        Some(ErrorCodeMetadata {
2436            added_in: "2.8.0",
2437            replaces: &[],
2438        }),
2439    )
2440});
2441
2442static CONTEXT_SELECTION_INVALID: LazyLock<ErrorCodeDefinition> = LazyLock::new(|| {
2443    ErrorCodeDefinition::new(
2444        "CONTEXT_SELECTION_INVALID".to_owned(),
2445        "The selection set is invalid".to_owned(),
2446        Some(ErrorCodeMetadata {
2447            added_in: "2.8.0",
2448            replaces: &[],
2449        }),
2450    )
2451});
2452
2453static INVALID_TAG_NAME: LazyLock<ErrorCodeDefinition> = LazyLock::new(|| {
2454    ErrorCodeDefinition::new(
2455        "INVALID_TAG_NAME".to_owned(),
2456        "Invalid value for argument \"name\" in application of @tag.".to_owned(),
2457        Some(ErrorCodeMetadata {
2458            added_in: "2.0.0",
2459            replaces: &[],
2460        }),
2461    )
2462});
2463
2464static CACHE_TAG_INVALID_FORMAT: LazyLock<ErrorCodeDefinition> = LazyLock::new(|| {
2465    ErrorCodeDefinition::new(
2466        "CACHE_TAG_INVALID_FORMAT".to_owned(),
2467        "Invalid format string in @cacheTag directive.".to_owned(),
2468        Some(ErrorCodeMetadata {
2469            added_in: "2.12.0",
2470            replaces: &[],
2471        }),
2472    )
2473});
2474
2475static CACHE_TAG_APPLIED_TO_NON_ROOT_FIELD: LazyLock<ErrorCodeDefinition> = LazyLock::new(|| {
2476    ErrorCodeDefinition::new(
2477        "CACHE_TAG_APPLIED_TO_NON_ROOT_FIELD".to_owned(),
2478        "@cacheTag on a field can only be applied on root fields.".to_owned(),
2479        Some(ErrorCodeMetadata {
2480            added_in: "2.12.0",
2481            replaces: &[],
2482        }),
2483    )
2484});
2485
2486static CACHE_TAG_INVALID_FORMAT_ARGUMENT_ON_ROOT_FIELD: LazyLock<ErrorCodeDefinition> =
2487    LazyLock::new(|| {
2488        ErrorCodeDefinition::new(
2489            "CACHE_TAG_INVALID_FORMAT_ARGUMENT_ON_ROOT_FIELD".to_owned(),
2490            "@cacheTag on root fields can only reference arguments using $args in format."
2491                .to_owned(),
2492            Some(ErrorCodeMetadata {
2493                added_in: "2.12.0",
2494                replaces: &[],
2495            }),
2496        )
2497    });
2498
2499static CACHE_TAG_INVALID_FORMAT_ARGUMENT_ON_ENTITY: LazyLock<ErrorCodeDefinition> = LazyLock::new(
2500    || {
2501        ErrorCodeDefinition::new(
2502            "CACHE_TAG_INVALID_FORMAT_ARGUMENT_ON_ENTITY".to_owned(),
2503            "cacheTag applied on types can only reference arguments in format using $key, and each referenced field must be a member of every @key field set.".to_owned(),
2504            Some(ErrorCodeMetadata {
2505                added_in: "2.12.0",
2506                replaces: &[],
2507            }),
2508        )
2509    },
2510);
2511
2512static CACHE_TAG_ENTITY_NOT_RESOLVABLE: LazyLock<ErrorCodeDefinition> = LazyLock::new(|| {
2513    ErrorCodeDefinition::new(
2514        "CACHE_TAG_ENTITY_NOT_RESOLVABLE".to_owned(),
2515        "@cacheTag can only apply on resolvable entities (object with at least one @key directive)."
2516            .to_owned(),
2517        Some(ErrorCodeMetadata {
2518            added_in: "2.12.0",
2519            replaces: &[],
2520        }),
2521    )
2522});
2523
2524static CONTEXTUAL_ARGUMENT_NOT_CONTEXTUAL_IN_ALL_SUBGRAPHS: LazyLock<ErrorCodeDefinition> =
2525    LazyLock::new(|| {
2526        ErrorCodeDefinition::new(
2527            "CONTEXTUAL_ARGUMENT_NOT_CONTEXTUAL_IN_ALL_SUBGRAPHS".to_owned(),
2528            "Argument on field is marked contextual in only some subgraphs".to_owned(),
2529            Some(ErrorCodeMetadata {
2530                added_in: "2.7.0",
2531                replaces: &[],
2532            }),
2533        )
2534    });
2535
2536static QUERY_ROOT_MISSING: LazyLock<ErrorCodeDefinition> = LazyLock::new(|| {
2537    ErrorCodeDefinition::new(
2538        "QUERY_ROOT_MISSING".to_owned(),
2539        "The schema has no query root type.".to_owned(),
2540        Some(ErrorCodeMetadata {
2541            added_in: "2.0.0",
2542            replaces: &[],
2543        }),
2544    )
2545});
2546
2547static AUTH_REQUIREMENTS_APPLIED_ON_INTERFACE: LazyLock<ErrorCodeDefinition> = LazyLock::new(
2548    || {
2549        ErrorCodeDefinition::new(
2550        "AUTH_REQUIREMENTS_APPLIED_ON_INTERFACE".to_owned(),
2551        "The @authenticated, @requiresScopes and @policy directive cannot be applied on interface, interface object or their fields.".to_owned(),
2552        Some(ErrorCodeMetadata {
2553            added_in: "2.9.4",
2554            replaces: &[],
2555        }),
2556    )
2557    },
2558);
2559
2560static MISSING_TRANSITIVE_AUTH_REQUIREMENTS: LazyLock<ErrorCodeDefinition> = LazyLock::new(|| {
2561    ErrorCodeDefinition::new(
2562            "MISSING_TRANSITIVE_AUTH_REQUIREMENTS".to_owned(),
2563            "Field missing transitive @authenticated, @requiresScopes and/or @policy auth requirements needed to access dependent data.".to_owned(),
2564            Some(ErrorCodeMetadata {
2565                added_in: "2.9.4",
2566                replaces: &[],
2567            }),
2568        )
2569});
2570
2571#[derive(Debug, PartialEq, strum_macros::EnumIter)]
2572pub enum ErrorCode {
2573    ErrorCodeMissing,
2574    Internal,
2575    ExtensionWithNoBase,
2576    InvalidGraphQL,
2577    DirectiveDefinitionInvalid,
2578    TypeDefinitionInvalid,
2579    UnsupportedLinkedFeature,
2580    UnknownFederationLinkVersion,
2581    UnknownLinkVersion,
2582    KeyFieldsHasArgs,
2583    ProvidesFieldsHasArgs,
2584    ProvidesFieldsMissingExternal,
2585    RequiresFieldsMissingExternal,
2586    KeyUnsupportedOnInterface,
2587    ProvidesUnsupportedOnInterface,
2588    RequiresUnsupportedOnInterface,
2589    KeyDirectiveInFieldsArgs,
2590    ProvidesDirectiveInFieldsArgs,
2591    RequiresDirectiveInFieldsArgs,
2592    ExternalUnused,
2593    TypeWithOnlyUnusedExternal,
2594    ProvidesOnNonObjectField,
2595    KeyInvalidFieldsType,
2596    ProvidesInvalidFieldsType,
2597    RequiresInvalidFieldsType,
2598    KeyInvalidFields,
2599    ProvidesInvalidFields,
2600    RequiresInvalidFields,
2601    KeyFieldsSelectInvalidType,
2602    RootQueryUsed,
2603    RootMutationUsed,
2604    RootSubscriptionUsed,
2605    InvalidSubgraphName,
2606    NoQueries,
2607    InterfaceFieldNoImplem,
2608    TypeKindMismatch,
2609    ExternalTypeMismatch,
2610    ExternalCollisionWithAnotherDirective,
2611    ExternalArgumentMissing,
2612    ExternalArgumentTypeMismatch,
2613    ExternalArgumentDefaultMismatch,
2614    ExternalOnInterface,
2615    MergedDirectiveApplicationOnExternal,
2616    FieldTypeMismatch,
2617    FieldArgumentTypeMismatch,
2618    InputFieldDefaultMismatch,
2619    FieldArgumentDefaultMismatch,
2620    ExternalMissingOnBase,
2621    InvalidFieldSharing,
2622    InvalidShareableUsage,
2623    InvalidLinkDirectiveUsage,
2624    InvalidLinkIdentifier,
2625    LinkImportNameMismatch,
2626    ReferencedInaccessible,
2627    DefaultValueUsesInaccessible,
2628    QueryRootTypeInaccessible,
2629    RequiredInaccessible,
2630    ImplementedByInaccessible,
2631    DisallowedInaccessible,
2632    OnlyInaccessibleChildren,
2633    RequiredInputFieldMissingInSomeSubgraph,
2634    RequiredArgumentMissingInSomeSubgraph,
2635    EmptyMergedInputType,
2636    InputFieldMergeFailed,
2637    EnumValueMismatch,
2638    EmptyMergedEnumType,
2639    ShareableHasMismatchedRuntimeTypes,
2640    SatisfiabilityError,
2641    MaxValidationSubgraphPathsExceeded,
2642    OverrideFromSelfError,
2643    OverrideSourceHasOverride,
2644    OverrideCollisionWithAnotherDirective,
2645    OverrideOnInterface,
2646    UnsupportedFeature,
2647    InvalidFederationSupergraph,
2648    DownstreamServiceError,
2649    DirectiveCompositionError,
2650    InterfaceObjectUsageError,
2651    InterfaceKeyNotOnImplementation,
2652    InterfaceKeyMissingImplementationType,
2653    UnsupportedFederationVersion,
2654    UnsupportedFederationDirective,
2655    QueryPlanComplexityExceededError,
2656    NoPlanFoundWithDisabledSubgraphs,
2657    CostAppliedToInterfaceField,
2658    ListSizeAppliedToNonList,
2659    ListSizeInvalidAssumedSize,
2660    ListSizeInvalidSlicingArgument,
2661    ListSizeInvalidSizedField,
2662    ContextNameInvalid,
2663    ContextNameContainsUnderscore,
2664    ContextNotSet,
2665    NoContextReferenced,
2666    NoSelectionForContext,
2667    ContextNoResolvableKey,
2668    ContextSelectionInvalid,
2669    InvalidTagName,
2670    CacheTagInvalidFormat,
2671    CacheTagAppliedToNonRootField,
2672    CacheTagInvalidFormatArgumentOnRootField,
2673    CacheTagInvalidFormatArgumentOnEntity,
2674    CacheTagEntityNotResolvable,
2675    OverrideLabelInvalid,
2676    ContextualArgumentNotContextualInAllSubgraphs,
2677    QueryRootMissing,
2678    AuthRequirementsAppliedOnInterface,
2679    MissingTransitiveAuthRequirements,
2680}
2681
2682impl ErrorCode {
2683    pub fn definition(&self) -> &'static ErrorCodeDefinition {
2684        match self {
2685            ErrorCode::Internal => &INTERNAL,
2686            ErrorCode::ExtensionWithNoBase => &EXTENSION_WITH_NO_BASE,
2687            ErrorCode::InvalidGraphQL => &INVALID_GRAPHQL,
2688            ErrorCode::DirectiveDefinitionInvalid => &DIRECTIVE_DEFINITION_INVALID,
2689            ErrorCode::TypeDefinitionInvalid => &TYPE_DEFINITION_INVALID,
2690            ErrorCode::UnsupportedLinkedFeature => &UNSUPPORTED_LINKED_FEATURE,
2691            ErrorCode::UnknownFederationLinkVersion => &UNKNOWN_FEDERATION_LINK_VERSION,
2692            ErrorCode::UnknownLinkVersion => &UNKNOWN_LINK_VERSION,
2693            ErrorCode::KeyFieldsHasArgs => &KEY_FIELDS_HAS_ARGS,
2694            ErrorCode::ProvidesFieldsHasArgs => &PROVIDES_FIELDS_HAS_ARGS,
2695            ErrorCode::ProvidesFieldsMissingExternal => &PROVIDES_FIELDS_MISSING_EXTERNAL,
2696            ErrorCode::RequiresFieldsMissingExternal => &REQUIRES_FIELDS_MISSING_EXTERNAL,
2697            ErrorCode::KeyUnsupportedOnInterface => &KEY_UNSUPPORTED_ON_INTERFACE,
2698            ErrorCode::ProvidesUnsupportedOnInterface => &PROVIDES_UNSUPPORTED_ON_INTERFACE,
2699            ErrorCode::RequiresUnsupportedOnInterface => &REQUIRES_UNSUPPORTED_ON_INTERFACE,
2700            ErrorCode::KeyDirectiveInFieldsArgs => &KEY_DIRECTIVE_IN_FIELDS_ARGS,
2701            ErrorCode::ProvidesDirectiveInFieldsArgs => &PROVIDES_DIRECTIVE_IN_FIELDS_ARGS,
2702            ErrorCode::RequiresDirectiveInFieldsArgs => &REQUIRES_DIRECTIVE_IN_FIELDS_ARGS,
2703            ErrorCode::ExternalUnused => &EXTERNAL_UNUSED,
2704            ErrorCode::ExternalCollisionWithAnotherDirective => {
2705                &EXTERNAL_COLLISION_WITH_ANOTHER_DIRECTIVE
2706            }
2707            ErrorCode::TypeWithOnlyUnusedExternal => &TYPE_WITH_ONLY_UNUSED_EXTERNAL,
2708            ErrorCode::ProvidesOnNonObjectField => &PROVIDES_ON_NON_OBJECT_FIELD,
2709            ErrorCode::KeyInvalidFieldsType => &KEY_INVALID_FIELDS_TYPE,
2710            ErrorCode::ProvidesInvalidFieldsType => &PROVIDES_INVALID_FIELDS_TYPE,
2711            ErrorCode::RequiresInvalidFieldsType => &REQUIRES_INVALID_FIELDS_TYPE,
2712            ErrorCode::KeyInvalidFields => &KEY_INVALID_FIELDS,
2713            ErrorCode::ProvidesInvalidFields => &PROVIDES_INVALID_FIELDS,
2714            ErrorCode::RequiresInvalidFields => &REQUIRES_INVALID_FIELDS,
2715            ErrorCode::KeyFieldsSelectInvalidType => &KEY_FIELDS_SELECT_INVALID_TYPE,
2716            ErrorCode::RootQueryUsed => &ROOT_QUERY_USED,
2717            ErrorCode::RootMutationUsed => &ROOT_MUTATION_USED,
2718            ErrorCode::RootSubscriptionUsed => &ROOT_SUBSCRIPTION_USED,
2719            ErrorCode::InvalidSubgraphName => &INVALID_SUBGRAPH_NAME,
2720            ErrorCode::NoQueries => &NO_QUERIES,
2721            ErrorCode::InterfaceFieldNoImplem => &INTERFACE_FIELD_NO_IMPLEM,
2722            ErrorCode::TypeKindMismatch => &TYPE_KIND_MISMATCH,
2723            ErrorCode::ExternalTypeMismatch => &EXTERNAL_TYPE_MISMATCH,
2724            ErrorCode::ExternalArgumentMissing => &EXTERNAL_ARGUMENT_MISSING,
2725            ErrorCode::ExternalArgumentTypeMismatch => &EXTERNAL_ARGUMENT_TYPE_MISMATCH,
2726            ErrorCode::ExternalArgumentDefaultMismatch => &EXTERNAL_ARGUMENT_DEFAULT_MISMATCH,
2727            ErrorCode::ExternalOnInterface => &EXTERNAL_ON_INTERFACE,
2728            ErrorCode::MergedDirectiveApplicationOnExternal => {
2729                &MERGED_DIRECTIVE_APPLICATION_ON_EXTERNAL
2730            }
2731            ErrorCode::FieldTypeMismatch => &FIELD_TYPE_MISMATCH,
2732            ErrorCode::FieldArgumentTypeMismatch => &FIELD_ARGUMENT_TYPE_MISMATCH,
2733            ErrorCode::InputFieldDefaultMismatch => &INPUT_FIELD_DEFAULT_MISMATCH,
2734            ErrorCode::FieldArgumentDefaultMismatch => &FIELD_ARGUMENT_DEFAULT_MISMATCH,
2735            ErrorCode::ExternalMissingOnBase => &EXTERNAL_MISSING_ON_BASE,
2736            ErrorCode::InvalidFieldSharing => &INVALID_FIELD_SHARING,
2737            ErrorCode::InvalidShareableUsage => &INVALID_SHAREABLE_USAGE,
2738            ErrorCode::InvalidLinkDirectiveUsage => &INVALID_LINK_DIRECTIVE_USAGE,
2739            ErrorCode::InvalidLinkIdentifier => &INVALID_LINK_IDENTIFIER,
2740            ErrorCode::LinkImportNameMismatch => &LINK_IMPORT_NAME_MISMATCH,
2741            ErrorCode::ReferencedInaccessible => &REFERENCED_INACCESSIBLE,
2742            ErrorCode::DefaultValueUsesInaccessible => &DEFAULT_VALUE_USES_INACCESSIBLE,
2743            ErrorCode::QueryRootTypeInaccessible => &QUERY_ROOT_TYPE_INACCESSIBLE,
2744            ErrorCode::RequiredInaccessible => &REQUIRED_INACCESSIBLE,
2745            ErrorCode::ImplementedByInaccessible => &IMPLEMENTED_BY_INACCESSIBLE,
2746            ErrorCode::DisallowedInaccessible => &DISALLOWED_INACCESSIBLE,
2747            ErrorCode::OnlyInaccessibleChildren => &ONLY_INACCESSIBLE_CHILDREN,
2748            ErrorCode::RequiredInputFieldMissingInSomeSubgraph => {
2749                &REQUIRED_INPUT_FIELD_MISSING_IN_SOME_SUBGRAPH
2750            }
2751            ErrorCode::RequiredArgumentMissingInSomeSubgraph => {
2752                &REQUIRED_ARGUMENT_MISSING_IN_SOME_SUBGRAPH
2753            }
2754            ErrorCode::EmptyMergedInputType => &EMPTY_MERGED_INPUT_TYPE,
2755            ErrorCode::InputFieldMergeFailed => &INPUT_FIELD_MERGE_FAILED,
2756            ErrorCode::EnumValueMismatch => &ENUM_VALUE_MISMATCH,
2757            ErrorCode::EmptyMergedEnumType => &EMPTY_MERGED_ENUM_TYPE,
2758            ErrorCode::ShareableHasMismatchedRuntimeTypes => {
2759                &SHAREABLE_HAS_MISMATCHED_RUNTIME_TYPES
2760            }
2761            ErrorCode::SatisfiabilityError => &SATISFIABILITY_ERROR,
2762            ErrorCode::MaxValidationSubgraphPathsExceeded => {
2763                &MAX_VALIDATION_SUBGRAPH_PATHS_EXCEEDED
2764            }
2765            ErrorCode::OverrideFromSelfError => &OVERRIDE_FROM_SELF_ERROR,
2766            ErrorCode::OverrideSourceHasOverride => &OVERRIDE_SOURCE_HAS_OVERRIDE,
2767            ErrorCode::OverrideCollisionWithAnotherDirective => {
2768                &OVERRIDE_COLLISION_WITH_ANOTHER_DIRECTIVE
2769            }
2770            ErrorCode::OverrideOnInterface => &OVERRIDE_ON_INTERFACE,
2771            ErrorCode::UnsupportedFeature => &UNSUPPORTED_FEATURE,
2772            ErrorCode::InvalidFederationSupergraph => &INVALID_FEDERATION_SUPERGRAPH,
2773            ErrorCode::DownstreamServiceError => &DOWNSTREAM_SERVICE_ERROR,
2774            ErrorCode::DirectiveCompositionError => &DIRECTIVE_COMPOSITION_ERROR,
2775            ErrorCode::InterfaceObjectUsageError => &INTERFACE_OBJECT_USAGE_ERROR,
2776            ErrorCode::InterfaceKeyNotOnImplementation => &INTERFACE_KEY_NOT_ON_IMPLEMENTATION,
2777            ErrorCode::InterfaceKeyMissingImplementationType => {
2778                &INTERFACE_KEY_MISSING_IMPLEMENTATION_TYPE
2779            }
2780            ErrorCode::UnsupportedFederationVersion => &UNSUPPORTED_FEDERATION_VERSION,
2781            ErrorCode::UnsupportedFederationDirective => &UNSUPPORTED_FEDERATION_DIRECTIVE,
2782            ErrorCode::QueryPlanComplexityExceededError => &QUERY_PLAN_COMPLEXITY_EXCEEDED,
2783            ErrorCode::NoPlanFoundWithDisabledSubgraphs => &NO_PLAN_FOUND_WITH_DISABLED_SUBGRAPHS,
2784            ErrorCode::CostAppliedToInterfaceField => &COST_APPLIED_TO_INTERFACE_FIELD,
2785            ErrorCode::ListSizeAppliedToNonList => &LIST_SIZE_APPLIED_TO_NON_LIST,
2786            ErrorCode::ListSizeInvalidAssumedSize => &LIST_SIZE_INVALID_ASSUMED_SIZE,
2787            ErrorCode::ListSizeInvalidSlicingArgument => &LIST_SIZE_INVALID_SLICING_ARGUMENT,
2788            ErrorCode::ListSizeInvalidSizedField => &LIST_SIZE_INVALID_SIZED_FIELD,
2789            ErrorCode::ContextNameContainsUnderscore => &CONTEXT_NAME_CONTAINS_UNDERSCORE,
2790            ErrorCode::ContextNameInvalid => &CONTEXT_NAME_INVALID,
2791            ErrorCode::ContextNotSet => &CONTEXT_NOT_SET,
2792            ErrorCode::NoContextReferenced => &NO_CONTEXT_REFERENCED,
2793            ErrorCode::NoSelectionForContext => &NO_SELECTION_FOR_CONTEXT,
2794            ErrorCode::ContextNoResolvableKey => &CONTEXT_NO_RESOLVABLE_KEY,
2795            ErrorCode::ContextSelectionInvalid => &CONTEXT_SELECTION_INVALID,
2796            ErrorCode::InvalidTagName => &INVALID_TAG_NAME,
2797            ErrorCode::CacheTagInvalidFormat => &CACHE_TAG_INVALID_FORMAT,
2798            ErrorCode::CacheTagAppliedToNonRootField => &CACHE_TAG_APPLIED_TO_NON_ROOT_FIELD,
2799            ErrorCode::CacheTagInvalidFormatArgumentOnRootField => {
2800                &CACHE_TAG_INVALID_FORMAT_ARGUMENT_ON_ROOT_FIELD
2801            }
2802            ErrorCode::CacheTagInvalidFormatArgumentOnEntity => {
2803                &CACHE_TAG_INVALID_FORMAT_ARGUMENT_ON_ENTITY
2804            }
2805            ErrorCode::CacheTagEntityNotResolvable => &CACHE_TAG_ENTITY_NOT_RESOLVABLE,
2806            ErrorCode::ErrorCodeMissing => &ERROR_CODE_MISSING,
2807            ErrorCode::OverrideLabelInvalid => &OVERRIDE_LABEL_INVALID,
2808            ErrorCode::ContextualArgumentNotContextualInAllSubgraphs => {
2809                &CONTEXTUAL_ARGUMENT_NOT_CONTEXTUAL_IN_ALL_SUBGRAPHS
2810            }
2811            ErrorCode::QueryRootMissing => &QUERY_ROOT_MISSING,
2812            ErrorCode::AuthRequirementsAppliedOnInterface => {
2813                &AUTH_REQUIREMENTS_APPLIED_ON_INTERFACE
2814            }
2815            ErrorCode::MissingTransitiveAuthRequirements => &MISSING_TRANSITIVE_AUTH_REQUIREMENTS,
2816        }
2817    }
2818}