GraphQL Errors

The GraphQL Content API responses via GitHub contains errors that occur during the different phases of a request (authentication, validation, schema generation and execution) dependencies. Among these errors there can also be other internal system errors.

The errors returned by the GraphQL API follow the GraphQL error spec via GitHub. There is an additional contentful object in the extensions error property with information relevant to the failed request to facilitate debugging and fixing problems. The contentful object contains the following properties:

  • code: unique error identifier.
  • requestId: unique request identifier.
  • details: optional object with details about a specific kind of error.

The following is an example of such a response from the API deployment:

1{
2 data: { // query data: optional, might be present in case of partial response
3 ...
4 },
5 errors: [{
6 message: 'Query execution error. Query too complex to be executed in allocated resources', // Human readable error message
7 locations: [{line: 4, column: 17}],
8 path: ['too', 'many', 'db_ops'],
9 extensions: {
10 contentful: {
11 code: 'RESOURCES_EXHAUSTED', // text error code
12 requestId: 'xxx' // id of current request
13 }
14 }
15 }]
16}

List of known errors

CategoryHTTP status codeMessageIs partial*
Authentication401ACCESS_TOKEN_MISSINGno
Authentication401ACCESS_TOKEN_INVALIDno
Schema generation422COLLIDING_TYPE_NAMESno
Schema generation422COLLIDING_FIELD_NAMESno
Schema generation422RESERVED_FIELD_NAMEno
Validation400UNKNOWN_ENVIRONMENTno
Validation400UNKNOWN_SPACEno
Validation400MISSING_QUERYno
Validation400QUERY_TOO_BIGno
Validation400INVALID_QUERY_FORMATno
Validation404PersistedQueryNotFoundno
Validation400PersistedQueryMismatchno
Validation400INVALID_VARIABLES_FORMATno
Validation400TOO_COMPLEX_QUERYno
Validation400QUERY_OPERATION_NAME_MISMATCHno
Query execution200UNKNOWN_LOCALEyes
Query execution200UNRESOLVABLE_LINKyes
Query execution200UNEXPECTED_LINKED_CONTENT_TYPEyes
Query execution200UNRESOLVABLE_RESOURCE_LINKyes
Query execution200RESOURCES_EXHAUSTEDyes
System errors200INTERNAL_SERVER_ERRORyes
System errors500INTERNAL_SERVER_ERRORno
System errors429RATE_LIMIT_EXCEEDEDno

Is partial indicates whether for given error partial data response is possible.

For more information, read our tutorials that cover frontend and backend technologies so you can implement GraphQL queries into your application, including languages JavaScript, Android and iOS (requires Apollo).

GraphQL Errors Explained

COLLIDING_TYPE_NAMES

The COLLIDING_TYPE_NAMES error is returned when one or more content type IDs are converted to the same GraphQL type name. For more information about this error, see the Colliding type names section.

Example

1{
2 errors: [{
3 message: "Schema generation failed. Type name generated for the content types 'A_car', 'a_car_' would be the same for all of them: 'ACar'",
4 extensions: {
5 contentful: {
6 code: 'COLLIDING_TYPE_NAMES',
7 details: {
8 collidingContentTypeIds: ['A_car', 'a_car_'],
9 resultingTypeName: 'ACar',
10 },
11 documentationUrl: 'xxxxxx/colliding-type-names',
12 requestId: 'xxx'
13 }
14 }
15 }]
16}

Solution

To prevent this error, make sure the content type IDs in your space environment cannot result in the same GraphQL type name. You can either enter two unique random IDs in the creation phase, or provide two distinct names that wouldn’t be converted to the same ID or GraphQL type name later on. For more information on how schemas and the type names are generated for your GraphQL schema, see the Schema generation section.

To fix this error, recreate one of the content types that have colliding IDs, making sure the new ID won’t collide with the second content type ID. You can also use the scripted approach described in the Scripting migrations with the Contentful CLI guide.

Note: Once the collision issue is fixed in Contentful, you also need to purge the cached content to push the fix into production.

COLLIDING_TYPE_NAMES during query execution

We dynamically create the types for GraphQL values based off of their names. As a result, users can inadvertently create naming collisions.

The following example is a common scenario of how a naming collision can occur:

  1. Create the following content types: BlogPost, BlogPostContent and BlogPostMoreContent.
  2. Add a reference field called content to your BlogPost content type, and allow it to link to BlogPostContent and BlogPostMoreContent.
  3. Create an entry of type BlogPost with its content field linking to an entry of type BlogPostMoreContent.
  4. Query the BlogPost entry including the linked entry. A generic error message is returned expecting only entries of type BlogPostContent instead of BlogPostMoreContent.

Here is a breakdown of what is actually happening:

When generating a BlogPostContent, we create an API-wide collection called BlogPostContentCollection for querying purposes. However, when generating the content field on a BlogPost, we also need to create a collection to enable querying. Unfortunately, this creates a name collision issue as both collections have the same name, but different types. This conflict can cause various issues in the codebase. In some cases, we are able to prevent schema generation. However, sometimes this occurs at query execution.

To fix this, determine what fields are causing a collision and rename one of the conflicting fields.

COLLIDING_FIELD_NAMES

The COLLIDING_FIELD_NAMES error is returned when several field IDs from the same content type are transformed into the same GraphQL field name.

Example

1{
2 errors: [
3 {
4 message: "Schema generation failed. Field name 'firstName' generated for the field 'first_name' in the content type 'brand' collides with an already existing field.",
5 extensions: {
6 contentful: {
7 code: "COLLIDING_FIELD_NAMES",
8 details: {
9 fieldApiName: "first_name",
10 contentTypeId: "brand",
11 fieldName: "firstName"
12 },
13 documentationUrl: 'xxxxxx/colliding-field-names',
14 requestId: 'xxx'
15 }
16 }
17 }
18 ]
19}

Solution

To prevent this error, make sure the field IDs you’re using on each content type cannot result in the same GraphQL field name. To fix this error, change the ID of one of the colliding fields in question using the web app or the Content Management API.

Note: Once the collision issue is fixed in Contentful, you also need to purge the cached content to push the fix into production.

RESERVED_FIELD_NAME

The RESERVED_FIELD_NAME error is returned when a field ID is transformed into a reserved GraphQL field name. Reserved field names are sys, linkedFrom and contentfulMetadata.

Example

1{
2 errors: [{
3 message: "Schema generation failed. Field name 'linkedFrom' generated for the field 'linked_from' in the content type 'blog' is reserved.",
4 extensions: {
5 contentful: {
6 code: 'RESERVED_FIELD_NAME',
7 details: {
8 contentTypeId: 'blog',
9 fieldId: 'sys'
10 },
11 documentationUrl: 'xxxxxx/reserved-field-names',
12 requestId: 'xxx'
13 }
14 }
15 }]
16}

Solution

To fix this error, change the field ID to a value that does not collide with any of the reserved names using the web app or the Content Management API.

UNKNOWN_ENVIRONMENT

The UNKNOWN_ENVIRONMENT error is returned when the requested environment does not exist or when the provided authentication token does not allow access to the specified environment.

Example

1{
2 errors: [{
3 message: 'Query cannot be executed. Requested environment does not exist in the space',
4 extensions: {
5 contentful: {
6 code: 'UNKNOWN_ENVIRONMENT',
7 details: {
8 availableEnvironments: ['master', 'qa']
9 },
10 documentationUrl: 'xxxxxx/unknown-environment',
11 requestId: 'xxx'
12 }
13 }
14 }]
15}

Solution

To fix this error you can:

  • request an environment from the list of environments that are already enabled for your content delivery token, or
  • adjust the token so that it has access to the environment you want to use in your query.

For more information on how authentication to the Content Delivery API and Content Preview API works and how you can configure them, see the Authentication section of the API reference.

UNKNOWN_SPACE

The UNKNOWN_SPACE error is returned when the space ID included in the URL is incorrect.

Example

1{
2 errors: [{
3 message: 'Query cannot be executed. The space could not be found.',
4 extensions: {
5 contentful: {
6 code: 'UNKNOWN_SPACE',
7 details: {
8 message: 'Check if the space id in the URL is correct.'
9 },
10 documentationUrl: 'xxxxxx/unknown-space',
11 requestId: 'xxx'
12 }
13 }
14 }]
15}

Solution

To fix this error you can:

  • request an environment from the list of environments that are already enabled for your content delivery token, or
  • adjust the token so that it has access to the environment you want to use in your query.

For more information on how authentication to the Content Delivery API and Content Preview API works and how you can configure them, see the Authentication section of the API reference.

MISSING_QUERY

The MISSING_QUERY error is returned when the POST request does not contain a payload or when the GET request does not contain the following query parameter: query.

Example

1{
2 errors: [{
3 message: 'Query cannot be executed. The request does not include a query neither in the body nor in the query string',
4 extensions: {
5 contentful: {
6 code: 'MISSING_QUERY',
7 documentationUrl: 'xxxxxx/missing-query',
8 requestId: 'xxx'
9 }
10 }
11 }]
12}

Solution

To fix this error, include a query in the body of a POST request or a query query parameter in the GET request.

QUERY_TOO_BIG

The QUERY_TOO_BIG error is returned when the query exceeds the maximum allowed size.

Example

1{
2 errors: [{
3 message: `Query cannot be executed. The maximum allowed size for a query is XXX bytes but it was YYY bytes`,
4 extensions: {
5 contentful: {
6 code: 'QUERY_TOO_BIG',
7 documentationUrl: 'xxxxxx/query-too-big',
8 querySizeInBytes: XXX,
9 requestId: 'xxx'
10 }
11 }
12 }]
13}

Solution

To fix this error, divide the query into smaller parts to get the information you need in multiple smaller queries.

INVALID_QUERY_FORMAT

The INVALID_QUERY_FORMAT error is returned when the query is not of type string.

Example

1{
2 errors: [{
3 message: "Query cannot be executed. The query is not a string",
4 extensions: {
5 contentful: {
6 code: 'INVALID_QUERY_FORMAT',
7 documentationUrl: 'xxxxxx/invalid-query-format',
8 requestId: 'xxx'
9 }
10 }
11 }]
12}

Solution

To fix this error, make sure the query passed in the request is of type string.

INVALID_VARIABLES_FORMAT

The INVALID_VARIABLES_FORMAT error is returned when the variables included in the request are not a valid JSON object.

Example

1{
2 errors: [{
3 message: "Query cannot be executed. The request variables are not a JSON object",
4 extensions: {
5 contentful: {
6 code: 'INVALID_VARIABLES_FORMAT',
7 documentationUrl: 'xxxxxx/invalid-variables-format',
8 requestId: 'xxx'
9 }
10 }
11 }]
12}

Solution

To fix this error, check the integrity of the variables sent and make sure the JSON object is valid.

PersistedQueryNotFound

The PersistedQueryNotFound error is returned when you send a hash for a query that is not cached in our server.

Example

1{
2 errors: [{
3 message: "PersistedQueryNotFound",
4 extensions: {
5 contentful: {
6 code: 'PERSISTED_QUERY_NOT_FOUND',
7 documentationUrl: 'xxxxxx/persisted-query-not-found',
8 requestId: 'xxx'
9 }
10 }
11 }]
12}

Solution

To fix this error, make sure you cached the query first by sending the hash and the query in a previous request.

PersistedQueryMismatch

The PersistedQueryMismatch error is returned when the sha256Hash does not match the expected query hash.

Example

1{
2 errors: [{
3 message: "PersistedQueryMismatch",
4 extensions: {
5 contentful: {
6 code: 'PERSISTED_QUERY_MISMATCH',
7 documentationUrl: 'xxxxxx/persisted-query-mismatch',
8 requestId: 'xxx'
9 }
10 }
11 }]
12}

Solution

To fix this error, make sure you hashed the query using the sha256Hash algorithm.

TOO_COMPLEX_QUERY

Disclaimer: The default complexity limit for collections is 100. The query complexity is calculated as the maximum number of entries and assets a query can potentially return.

The TOO_COMPLEX_QUERY error is returned when the calculated query complexity exceeds the maximum complexity allowed.

Example

1{
2 errors: [{
3 message: `Query cannot be executed. The maximum allowed complexity for a query is 10000 but it was 20000. Simplify the query e.g. by setting lower limits for collections.`,
4 extensions: {
5 contentful: {
6 code: 'TOO_COMPLEX_QUERY',
7 details: {
8 cost: 10000,
9 maximumCost: 20000
10 },
11 documentationUrl: 'xxxxxx/too-complex-query',
12 requestId: 'xxx'
13 }
14 }
15 }]
16}

Solution

To avoid this issue, simplify the query complexity by setting a lower limit in the GraphQL query. You can also limit the depth of the query. For reference fields, it’s recommended to set a limit on the number of allowed links in the content modeling section. If there is a lower number than the default 1000, it will be used to calculate the overall complexity instead.

Examples of actions to optimize a query

  • Make sure all the collections queried have a limit set on them:
1# Avoid:
2query {
3 lessonCollection {
4 items {
5 title
6 }
7 }
8}
9
10# Optimized:
11query {
12 lessonCollection(limit: 20) {
13 items {
14 title
15 }
16 }
17}
  • Lower the limits on nested collections to significantly reduce the resulting cost:
1# Avoid:
2query {
3 lessonCollection(limit: 200) {
4 items {
5 title
6 imageCollection {
7 title
8 url
9 }
10 }
11 }
12}
13
14# Optimized:
15query {
16 lessonCollection(limit: 20) {
17 items {
18 title
19 imageCollection(limit: 10) {
20 title
21 url
22 }
23 }
24 }
25}
  • If you know how many entries can be in a specific collection, set the limit to that number or lower.
1# Avoid:
2query {
3 lessonCollection(limit: 200) {
4 items {
5 title
6 imageCollection(limit: 100) {
7 title
8 url
9 }
10 }
11 }
12}
13# if imageCollection contains only 50 entries
14# then it’s better to lower the limit to 50.
15
16# Optimized
17query {
18 lessonCollection(limit: 200) {
19 items {
20 title
21 imageCollection(limit: 50) {
22 title
23 url
24 }
25 }
26 }
27}
  • If you have the linkedFrom field and you know the exact number of entries you are linking to, set the limit to that number:
1# Avoid:
2query {
3 catCollection(limit: 20) {
4 items {
5 name
6 linkedFrom {
7 entryCollection {
8 items {
9 ... on FriendlyUser {
10 firstName
11 }
12 }
13 }
14 }
15 }
16 }
17}
18# if you know that the number
19# of entries linked from is 5
20# set the limit to 5
21
22# Optimized:
23query {
24 catCollection(limit: 20) {
25 items {
26 name
27 linkedFrom {
28 entryCollection(limit: 5) {
29 items {
30 ... on FriendlyUser {
31 firstName
32 }
33 }
34 }
35 }
36 }
37 }
38}
  • If the query is too deep, fetch the IDs of a nested collection and use a separate query for that collection:
1# Avoid:
2query {
3 lessonCollection(limit: 200) {
4 items {
5 title
6 teacher {
7 name
8 primaryLessonsCollection(limit: 100) {
9 items {
10 title
11 }
12 }
13 }
14 }
15 }
16}
17
18# Optimized:
19query {
20 lessonCollection(limit: 200) {
21 items {
22 title
23 teacher {
24 sys {
25 id
26 }
27 }
28 }
29 }
30}
31
32# Get all the IDs in teacher.sys.id and use another query:
33query($teacherIds: [String]) {
34 teacherCollection(where: {
35 sys: { id_in: $teacherIds } }
36 ) {
37 items {
38 name
39 primaryLessonsCollection(limit: 100) {
40 items {
41 title
42 }
43 }
44 }
45 }
46}

QUERY_OPERATION_NAME_MISMATCH

The QUERY_OPERATION_NAME_MISMATCH error is returned when a GraphQL request is received without a valid or matching operation name. The server cannot determine which operation to execute based on the provided operation name. The error message includes the received operation name and the available operation names found in the query.

Example

1{
2 "errors": [{
3 "message": "Could not determine what operation to execute, received 'blogPostCollectionQuery3' but found 'blogPostCollectionQuery1, blogPostCollectionQuery2'",
4 "extensions": {
5 "contentful": {
6 "code": "QUERY_OPERATION_NAME_MISMATCH",
7 "requestId": "xxx"
8 }
9 }
10 }]
11}

Possible causes

  • The operation name provided in the GraphQL request does not match any of the operation names defined in the query.
  • The GraphQL query does not contain any operation names.

Solution

  • Ensure that the operation name provided in the request is spelled correctly and matches one of the operation names defined in the query.
  • If the GraphQL query does not contain any operation names, make sure to include the operation name when sending the request.

UNKNOWN_LOCALE

The UNKNOWN_LOCALE error is returned when the requested locale does not exist.

Example

1{
2 data: {
3 pet: null
4 },
5 errors: [{
6 message: "Query execution error. Requested locale 'de-DE' does not exist in the space",
7 locations: [{ line: 0, column: 0 }],
8 path: ['pet'],
9 extensions: {
10 contentful: {
11 code: 'UNKNOWN_LOCALE',
12 details: {
13 availableLocaleCodes: ['en-US', 'es-ES']
14 },
15 documentationUrl: 'xxxxxx/unknown-locale',
16 requestId: 'xxx'
17 }
18 }
19 }]
20}

Solution

To fix this error, request one of the available locale codes returned in the error details. For more information about editing a locale, see the Localization with Contentful tutorial.

The UNRESOLVABLE_LINK error is returned when a link cannot be resolved because the target entity does not exist or it is not published.

NOTES:

  • When a link cannot be resolved, a null value is returned on that field.
  • When a link in an array cannot be resolved, a null value on its position is returned.
  • For each link that cannot be resolved, an error object with the details is sent with the response.

To distinguish between single entity links and array links, pay attention to the type in the GraphQL schema and the actual GraphQL response.

Examples

1// Single entity link
2{
3 data: {
4 pet: null
5 },
6 errors: [{
7 message: "Query execution error. Link to entry 'my-dog' on field 'pet' within type 'Blog' cannot be resolved",
8 locations: [{line: 0, column: 0}],
9 path: ['pet'],
10 extensions: {
11 contentful: {
12 code: 'UNRESOLVABLE_LINK',
13 details: {
14 type: 'FriendlyUser',
15 field: 'pet',
16 linkType: 'entry',
17 linkId: 'my-dog'
18 },
19 documentationUrl: 'xxxxxx/unresolvable-link',
20 requestId: 'xxx'
21 }
22 }
23 }]
24}
25
26// Array link
27// Note that we return one error per unresolvable link, almost identical, except by the `path`
28{
29 data: {
30 pets: [
31 { name: 'fido' },
32 null,
33 { name: 'scuby' },
34 null
35 ]
36 },
37 errors: [{
38 message: "Query execution error. Link to entry 'my-dog' on field 'pets' within type 'Blog' cannot be resolved",
39 path: ['pets', 1],
40 extensions: {
41 contentful: {
42 code: 'UNRESOLVABLE_LINK',
43 details: {
44 type: 'FriendlyUser',
45 field: 'pets',
46 linkType: 'entry',
47 linkId: 'my-dog'
48 },
49 documentationUrl: 'xxxxxx/unresolvable-link',
50 requestId: 'xxx'
51 }
52 }
53 },
54 {
55 message: "Query execution error. Link to entry 'my-dog' on field 'pets' within type 'Blog' cannot be resolved",
56 path: ['pets', 2],
57 extensions: {
58 contentful: {
59 code: 'UNRESOLVABLE_LINK',
60 details: {
61 type: 'FriendlyUser',
62 field: 'pets',
63 linkType: 'entry',
64 linkId: 'my-dog'
65 },
66 documentationUrl: 'xxxxxx/unresolvable-link',
67 requestId: 'xxx'
68 }
69 }
70 }]
71}

Solution

To fix this error, adjust your query to only request entities that exist and are published. Additionally, you can handle this specific error gracefully in your application.

You can skip over unresolvable links by filtering where the sys.id_exists is true.

Note: To use the filter, you must have a validation rule set on the many reference field that makes it only accept one content type.

1query {
2 friendlyUserCollection {
3 items {
4 firstName
5 catCollection(limit: 100, where:{sys:{id_exists:true}}) {
6 items {
7 name
8 }
9 }
10 }
11 }
12}

UNEXPECTED_LINKED_CONTENT_TYPE

The UNEXPECTED_LINKED_CONTENT_TYPE error is returned when the linked entry has an unexpected content type linked to it in the validations. This happens when a validation in a field is changed to disallow a specific content type that was previously allowed, while entries with links to that content type still exist.

Example

1[{
2 message: "Query execution error. Link from entry 'blog-1' to entry 'Tom' on field 'externalAuthor' within type 'Blog' returned an unexpected content type",
3 path: ['blog', 'externalAuthor'],
4 extensions: {
5 contentful: {
6 code: 'UNEXPECTED_LINKED_CONTENT_TYPE',
7 details: {
8 type: 'Blog',
9 field: 'externalAuthor',
10 entryId: 'Tom',
11 contentType: 'person',
12 permittedContentTypes: ['someOtherContentType'],
13 linkingEntryId: 'blog-1',
14 },
15 documentationUrl: 'xxxxxx/unexpected-linked-content-type',
16 requestId: 'xxx',
17 },
18 },
19}]

Solution

To fix this error, you can remove the links to entries to content types that aren’t allowed anymore, or adjust the allowed content types in the linked entry.

RESOURCES_EXHAUSTED

The RESOURCES_EXHAUSTED error is returned when the GraphQL query has used more resources for its execution than allowed.

Example

1{
2 data: {
3 too: {
4 name: 'Josh',
5 age: 22,
6 many: {
7 db_ops: null,
8 }
9 }
10 },
11 errors: [{
12 message: 'Query execution error. Query too complex to be executed in allocated resources',
13 locations: [{ line: 4, column: 17 }],
14 path: ['too', 'many', 'db_ops'],
15 extensions: {
16 contentful: {
17 code: 'RESOURCES_EXHAUSTED',
18 documentationUrl: 'xxxxxx/unresolvable-link',
19 requestId: 'xxx'
20 }
21 }
22 }]
23}

Solution

To fix this error, split the query into multiple simple queries.

The UNRESOLVABLE_RESOURCE_LINK error is returned when a Custom external references or Functions query fails.

Example

1[
2 {
3 "message": "Query execution error. 'vendorId' link cannot be resolved",
4 "extensions": {
5 "contentful": {
6 "code": "UNRESOLVABLE_RESOURCE_LINK",
7 "documentationUrl": "xxxxxx/unresolvable-resource-link",
8 "requestId": "xxx",
9 "details": {
10 "app": "vendorId"
11 }
12 }
13 },
14 "locations": [
15 { "line": 4, "column": 17 }
16 ],
17 "path": ["contentTypeId", "fieldId"]
18 }
19]

Solution

To fix this error, you need to check your third-party data query and your entry that is linked to your app.