Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

A list of validation errors in Apollo Federation #48

Draft
wants to merge 1 commit into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
169 changes: 169 additions & 0 deletions rfcs/apollo-federation-errors/subgraph-level.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,169 @@
# Subgraph-level Validation Errors

A list of validation errors (not all of them) that can be returned when validating a subgraph, in
isolation.

### QUERY_ROOT_TYPE_INACCESSIBLE

The root query type must be accessible.

Example error message:

```
Type "Query" is @inaccessible but is the root query type, which must be in the API schema.
```

### INVALID_SHAREABLE_USAGE

Example error message:

```
Invalid use of @shareable on field "Product.name": only object type fields can be marked with @shareable
```

### REQUIRES_UNSUPPORTED_ON_INTERFACE

Example error messages:

```
Cannot use @requires on field "Product.price" of parent type "Product": @requires is not yet supported within interfaces.
```

### REQUIRES_INVALID_FIELDS_TYPE

```
On field "Product.price", for @requires(fields: "<value>"): Invalid value for argument "fields": must be a string.
```

### REQUIRES_INVALID_FIELDS

```
On field "Product.price", for @requires(fields: "<value>"): <error message>

On field "Product.price", for @requires(fields: "<value>"): Cannot query field "uuid" on type "Product" (if the field is defined in another subgraph, you need to add it to this subgraph with @external).

On field "Product.price", for @requires(fields: "<value>"): Unknown directive "@<directive-name>" in selection
```

### REQUIRES_DIRECTIVE_IN_FIELDS_ARG

```
On field "Product.price", for @requires(fields: "<value>"): cannot have directive applications in the @requires(fields:) argument but found @<directive-name>.
```

### REQUIRES_FIELDS_MISSING_EXTERNAL

```
On field "Product.price", for @requires(fields: "<value>"): field "Product.uuid" should not be part of a @requires since it is already provided by this subgraph (it is not marked @external)
```

### PROVIDES_ON_NON_OBJECT_FIELD

```
Invalid @provides directive on field "Price.price": field has type "Float!" which is not a Composite Type
```

### PROVIDES_UNSUPPORTED_ON_INTERFACE

```
Cannot use @provides on field "Product.price" of parent type "Product": @provides is not yet supported within interfaces
```

### PROVIDES_INVALID_FIELDS_TYPE

```
On field "Product.price", for @provides(fields: "<value>"): Invalid value for argument "fields": must be a string.
```

### PROVIDES_INVALID_FIELDS

```
On field "Product.price", for @provides(fields: "<value>"): <error message>

On field "Product.price", for @provides(fields: "<value>"): Invalid empty selection set for field "Price.details" of non-leaf type "Price"

On field "Product.price", for @provides(fields: "<value>"): Cannot query field "details" on type "Price" (if the field is defined in another subgraph, you need to add it to this subgraph with @external).

On field "Product.price", for @provides(fields: "<value>"): Unknown directive "@<directive-name>" in selection
```

### PROVIDES_DIRECTIVE_IN_FIELDS_ARG

```
On field "Product.price", for @provides(fields: "<value>"): cannot have directive applications in the @provides(fields:) argument but found @<directive-name>.
```

### PROVIDES_FIELDS_HAS_ARGS

```
On field "Product.price", for @provides(fields: "<value>"): field "Price.details" cannot be included because it has arguments (fields with argument are not allowed in @provides)
```

### PROVIDES_FIELDS_MISSING_EXTERNAL

```
On field "Product.price", for @provides(fields: "<value>"): field "Price.details" should not be part of a @provides since it is already provided by this subgraph (it is not marked @external)

On field "Product.price", for @provides(fields: "<value>"): field "Price.details" should not be part of a @provides since it is already "effectively" provided by this subgraph (while it is marked @external, it is a @key field of an extension type, which are not internally considered external for historical/backward compatibility reasons)
```

### KEY_UNSUPPORTED_ON_INTERFACE

```
Cannot use @key on interface "Node": @key is not yet supported on interfaces
```

### KEY_INVALID_FIELDS_TYPE

```
On type "Product", for @key(fields: "<value>"): Invalid value for argument "fields": must be a string.
```

### KEY_INVALID_FIELDS

```
On type "Product", for @key(fields: "<value>"): <error-message>

On type "Product", for @key(fields: "<value>"): Cannot query field "name" on type "Product" (the field should either be added to this subgraph or, if it should not be resolved by this subgraph, you need to add it to this subgraph with @external).

On type "Product", for @key(fields: "<value>"): Unknown directive "@<directive-name>"
```

### KEY_DIRECTIVE_IN_FIELDS_ARG

```
On type "Product", for @key(fields: "<value>"): cannot have directive applications in the @key(fields:) argument but found @<directive-name>.
```

### KEY_FIELDS_HAS_ARGS

```
On type "Product", for @key(fields: "<value>"): field Product.name cannot be included because it has arguments (fields with argument are not allowed in @key)
```

### KEY_FIELDS_SELECT_INVALID_TYPE

```
On type "Product", for @key(fields: "<value>"): field "Product.price" is a Interface type which is not allowed in @key
```

### INTERFACE_KEY_NOT_ON_IMPLEMENTATION

```
Key @key(fields: "<value>") on interface type "Product" is missing on implementation type "<type-name>".
```

### MERGED_DIRECTIVE_APPLICATION_ON_EXTERNAL

It applies mostly to `@tag` and `@inaccessible` directives. They cannot overlap with `@external`
fields.

```
Cannot apply merged directive <directive> to external field "Product.price"
```

### EXTERNAL_UNUSED

```
Field "Product.name" is marked @external but is not used in any federation directive (@key, @provides, @requires) or to satisfy an interface; the field declaration has no use and should be removed (or the field should not be @external).
```
172 changes: 172 additions & 0 deletions rfcs/apollo-federation-errors/supergraph-level.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,172 @@
# Supergraph-level Validation Errors

A list of validation errors (not all of them) that can be returned only when validating a
supergraph, with context from all subgraphs.

### TYPE_KIND_MISMATCH

```
Type "Product" has mismatched kind: it is defined as Object Type in subgraph Foo but Interface Type in subgraph Bar
```

### NO_QUERIES

```
No queries found in any subgraph: a supergraph must have a query root type.
```

### REQUIRED_INPUT_FIELD_MISSING_IN_SOME_SUBGRAPH

```
Input object field "AddProductInput.price" is required in some subgraphs but does not appear in all subgraphs: it is required in subgraphs Foo and Bar, but does not appear in Baz.
```

### REQUIRED_INACCESSIBLE

```
Input field "AddProductInput.price" is @inaccessible but is a required input field of its type.

Argument "Product.price(currency:)" is @inaccessible but is a required argument of its field.
```

### REQUIRED_ARGUMENT_MISSING_IN_SOME_SUBGRAPH

```
Argument "Product.price(currency:)" is required in some subgraphs but does not appear in all subgraphs: it is required in subgraphs Foo and Bar, but does not appear in Baz.
```

### REFERENCED_INACCESSIBLE

```
Type "Price" is @inaccessible but is referenced by "Product.price", which is in the API schema.

Type "CurrencyInput" is @inaccessible but is referenced by "Product.price(currency:)", which is in the API schema.
```

### ONLY_INACCESSIBLE_CHILDREN

```
Type "CategoryEnum" is in the API schema but all of its values are @inaccessible.

Type "ProductObject" is in the API schema but all of its fields are @inaccessible.
Type "ProductInterface" is in the API schema but all of its fields are @inaccessible.
Type "AddProductInput" is in the API schema but all of its fields are @inaccessible.
```

### INVALID_FIELD_SHARING

```
Fields on root level subscription object cannot be marked as shareable.

Non-shareable field "Product.price" is resolved from multiple subgraphs: it is resolved from subgraphs Foo and Bar, and defined as non-shareable in Bar.

Non-shareable field "Product.price" is resolved from multiple subgraphs: it is resolved from subgraphs Foo and Bar, and defined as non-shareable in all of them.
```

### INTERFACE_KEY_MISSING_IMPLEMENTATION_TYPE

```
[Bar] Interface type "Node" has a resolvable key (@key(fields: "<value>")) in subgraph "Bar" but that subgraph is missing some of the supergraph implementation types of "Node". Subgraph "Bar" should define types "Product" and "Price" (and have them implement "Node").
```

### INTERFACE_FIELD_NO_IMPLEM

```
Interface field "ProductIf.name" is declared in subgraphs Foo and Bar but type "Book", which implements "ProductIf" in subgraph "Baz" does not have field "name".
```

### EMPTY_MERGED_INPUT_TYPE

```
None of the fields of input object type "AddProductInput" are consistently defined in all the subgraphs defining that type. As only fields common to all subgraphs are merged, this would result in an empty type.
```

#### INPUT_FIELD_DEFAULT_MISMATCH

```
Input field "AddProductInput.isAvailable" has incompatible default values across subgraphs: it has default value "true" in subgraph Foo, but default value "false" in subgraph Bar.
```

### FIELD_TYPE_MISMATCH

Applies to input object types, object types, and interface types.

```
Type of field "Product.price" is incompatible across subgraphs: it has type "Price" in subgraph Foo, but type "Float" in subgraph Bar.
```

### FIELD_ARGUMENT_TYPE_MISMATCH

```
Type of argument "Product.price(currency:)" is incompatible across subgraphs: it has type "Currency"
in subgraph Foo, but type "String" in subgraph Bar.
```

### FIELD_ARGUMENT_DEFAULT_MISMATCH

```
Argument "Product.price(currency:)" has incompatible default values across subgraphs: it has default value "USD" in subgraph Foo, but default value "EUR" in subgraph Bar.
```

### EXTERNAL_TYPE_MISMATCH

```
Type of field "Product.price" is incompatible across subgraphs (where marked @external): it has type "Price" in subgraph Foo, but type "Float" in subgraph Bar.
```

### EXTERNAL_MISSING_ON_BASE

```
Type "Product" is marked @external on all the subgraphs in which it is listed (Foo, Bar).

Field "Product.price" is marked @external on all the subgraphs in which it is listed (Foo, Bar).
```

### EXTERNAL_ARGUMENT_MISSING

```
Field "Product.price" is missing argument "currency" in some subgraphs where it is marked @external: argument "currency" is declared in subgraphs Foo and Bar, but not in subgraph Baz (where "Product.price" is @external)
```

### EXTENSION_WITH_NO_BASE

```
[Bar] Type "Product" is an extension type, but there is no type definition for "Product" in any subgraph.
```

### ENUM_VALUE_MISMATCH

```
Enum type "CurrencyEnum" is used as both input type (for example, as type of "AddProductInput.currency") and output type (for example, as type of "Product.price.currency"), but value "PLN" is not defined in all the subgraphs defining "CurrencyEnum": "PLN" is defined in subgraph Foo, but not in subgraphs Bar and Baz.
```

### EMPTY_MERGED_ENUM_TYPE

```
None of the values of enum type "Currency" are defined consistently in all the subgraphs defining that type. As only values common to all subgraphs are merged, this would result in an empty type.
```

### DEFAULT_VALUE_USES_INACCESSIBLE

```
Enum value "Currency.PLN" is @inaccessible but is used in the default value of "AddProductInput.price", which is in the API schema.
```

### SATISFIABILITY_ERROR

Next to every error message, there's an example query path that cannot be satisfied by the
supergraph.

```
Cannot move to subgraph "foo" using @key(fields: "<value>") of "Product", the key field(s) cannot be resolved from subgraph "bar".

Cannot satisfy @require conditions on field "Product.price".

Field "Product.price" is not resolvable because marked @external.

Cannot find field "Product.prince".

Cannot move to subgraph "bar", which has field "Product.name", because type "Product" has no @key defined in subgraph "foo".


```
Loading