This article is about fixing Graphql Cannot return null for non-nullable field in API Platform API Platform
  • 29-Jan-2023
Lightrun Team
Author Lightrun Team
Share
This article is about fixing Graphql Cannot return null for non-nullable field in API Platform API Platform

Graphql: Cannot return null for non-nullable field in API Platform API Platform

Lightrun Team
Lightrun Team
29-Jan-2023

Explanation of the problem

The user is encountering an issue when querying a list of contacts using GraphQL. The error message returned states “Cannot return null for non-nullable field Contact.role.”. This issue is specific to a single contact (with ID 219) and all other contacts are returned without error. The user has checked the data for this contact in the database and it appears to be valid, with no unexpected null values in non-nullable fields.

When querying the specific contact (ID 219) using the same fields, the query returns successfully. However, when the field “role” is set to accept nullable values, the list query no longer raises an error but the returned data for contact ID 219 is empty. The user is unsure of the cause of this behavior and is seeking guidance on where to look for a solution.

{
  contacts(first: 30, after: "MjAw") {
    edges {
      node {
        _id
        salesforceId
        email
        role
        passwordSent
        firstName
        lastName
        phone
        mobilePhone
        function {
          id
          label
        }
        contactOwner {
          id
          salesforceId
        }
        account {
          salesforceId
        }
        contactTitle {
          salesforceId
        }
        department {
          salesforceId
        }
        lastUpstreamSync
      }
    }
  }
}
{
  "errors": [
    {
      "debugMessage": "Cannot return null for non-nullable field Contact.role.",
      "message": "Internal server error",
      "category": "internal",
      "locations": [
        {
          "line": 8,
          "column": 9
        }
      ],
      "path": [
        "contacts",
        "edges",
        16,
        "node",
        "role"
      ]
    }
  ],
  "data": {
    "contacts": {
      "edges": [
        // some contacts...
        {
          "node": null
        },
        // some contacts...
      ]
    }
  }
}
{
  contact(id: "/v2/contacts/219") {
      _id
      salesforceId
      email
      role
      passwordSent
      firstName
      lastName
      phone
      mobilePhone
      function {
        id
        label
      }
      contactOwner {
        id
        salesforceId
      }
      account {
        salesforceId
      }
      contactTitle {
        salesforceId
      }
      department {
        salesforceId
      }
      lastUpstreamSync
    }
}
{
  "data": {
    "contact": {
      "_id": 219,
      "salesforceId": "obfurscated",
      "email": "obfurscated@obfurscated.fr",
      "role": "ROLE_ADMINISTRATOR",
      "passwordSent": false,
      "firstName": "obfurscated",
      "lastName": "obfurscated",
      "phone": "",
      "mobilePhone": "obfurscated",
      "function": {

Troubleshooting with the Lightrun Developer Observability Platform

Getting a sense of what’s actually happening inside a live application is a frustrating experience, one that relies mostly on querying and observing whatever logs were written during development.
Lightrun is a Developer Observability Platform, allowing developers to add telemetry to live applications in real-time, on-demand, and right from the IDE.

  • Instantly add logs to, set metrics in, and take snapshots of live applications
  • Insights delivered straight to your IDE or CLI
  • Works where you do: dev, QA, staging, CI/CD, and production

Start for free today

Problem solution for Graphql: Cannot return null for non-nullable field in API Platform API Platform

The issue being described is that a GraphQL query is returning an error “Cannot return null for non-nullable field Contact.role.” when attempting to retrieve a specific contact by ID. The error is specific to this one contact, and all other contacts are returned without issue. The individual contact can be successfully retrieved using a separate query with the same fields.

The error is occurring when using the following query to retrieve a list of contacts:

{
  contacts(first: 30, after: "MjAw") {
    edges {
      node {
        _id
        salesforceId
        email
        role
        passwordSent
        firstName
        lastName
        phone
        mobilePhone
        function {
          id
          label
        }
        contactOwner {
          id
          salesforceId
        }
        account {
          salesforceId
        }
        contactTitle {
          salesforceId
        }
        department {
          salesforceId
        }
        lastUpstreamSync
      }
    }
  }
}

When altering the “role” field to be nullable, the error is resolved but the contact returns with all fields set to null. The issue may be related to the specific data stored in the contact or in the related entities. Further investigation is necessary to determine the cause of the error.

Other popular problems with API Platform

Problem: InvalidArgumentException when using Symfony Serializer

When using Symfony Serializer to deserialize data in API Platform, an InvalidArgumentException may be thrown with the message “Could not determine the class of the parameter”. This occurs when the Serializer is unable to determine the class to deserialize the data into.

Solution:

To resolve this issue, the class to deserialize the data into must be specified. This can be done by adding the @Groups annotation to the parameter and setting the serializer_groups attribute to an array containing the name of the class.

use Symfony\Component\Serializer\Annotation\Groups;

class Contact {
    /**
     * @Groups({"create"})
     * @var string
     */
    private $name;

    public function __construct(string $name)
    {
        $this->name = $name;
    }
}

In the controller action :

use Symfony\Component\Serializer\SerializerInterface;
use Symfony\Component\HttpFoundation\Request;

class ContactController {
    public function createContact(Request $request, SerializerInterface $serializer)
    {
        $data = json_decode($request->getContent(), true);
        $contact = $serializer->deserialize($data, Contact::class, 'json', ['groups' => ['create']]);
    }
}

Problem: CORS error when making cross-origin requests

When making cross-origin requests to an API built with API Platform, a CORS error may be encountered, preventing the request from being processed. This occurs because the browser will block the request if the server does not include the appropriate CORS headers.

Solution:

To resolve this issue, CORS headers must be added to the server’s response. This can be done by adding the following code to the config/packages/cors.yaml file, which will allow all origins to make requests to the API.

nelmio_cors:
    defaults:
        allow_credentials: false
        allow_origin: ['*']
        allow_headers: ['*']
        allow_methods: ['GET', 'POST', 'PUT', 'DELETE']
        expose_headers: []
        max_age: 3600

Problem: Error when using GraphQL and Doctrine

When using GraphQL and Doctrine together, an error may be encountered when attempting to return a non-nullable field that contains a null value. This occurs because GraphQL requires all non-nullable fields to contain a value, while Doctrine allows null values in fields that are not marked as “not null”.

Solution:

To resolve this issue, the field in question must be marked as nullable in the Doctrine mapping. This can be done by adding the nullable attribute to the field annotation.

use Doctrine\ORM\Mapping as ORM;

class Contact {
    /**
     * @ORM\Column(type="string", nullable=true)
     */
    private $role;
}

Alternatively, you can update the GraphQL type to expect nullable fields with the ! sign

type Contact {
    role: String!
}

A brief introduction to API Platform

API Platform is an open-source framework for building API-driven projects. It is built on top of the Symfony framework and utilizes several components such as Doctrine, Symfony Serializer, and Symfony Validator to provide a powerful and flexible toolset for building APIs. API Platform provides several features out of the box such as data validation, pagination, filtering, and caching, as well as support for CRUD operations, data serialization, and schema generation. This allows developers to quickly and easily build robust and efficient APIs.

One of the main benefits of using API Platform is its support for the GraphQL and REST specification. This allows developers to create a flexible and powerful API that can be consumed by a wide range of clients, including web and mobile applications. Additionally, API Platform provides support for the JSON-LD and HAL+JSON formats, which can be used to create hypermedia-driven APIs that are easy to discover and navigate. The framework also provides several built-in features such as pagination, filtering, and caching which can help optimize the performance of the API. Furthermore, the framework is extensible, which allows developers to add custom functionality to the API as needed.

Most popular use cases for API Platform

  1. API Platform is a powerful tool for creating robust, high-performance APIs for web and mobile applications. It provides a set of built-in features, such as automatic data validation, error handling, and pagination, that make it easy to create APIs that are both secure and efficient. Additionally, API Platform supports a wide range of data formats, including JSON, JSON-LD, and HAL, so you can easily create APIs that are compatible with a variety of client applications.
  2. API Platform is also designed to work seamlessly with a variety of backends, including traditional relational databases, MongoDB, Elasticsearch, and more. This allows you to easily expose your existing data and business logic through a well-defined API, without having to worry about the underlying infrastructure. Additionally, API Platform supports a wide range of authentication and authorization schemes, so you can easily secure your API and control access to your data.
  3. API Platform can be used to easily create a GraphQL API. Using the built-in GraphQL support, you can define your API’s types, queries and mutations in PHP. The following code block shows an example of a GraphQL query that is defined using API Platform.
type Query {
    books: [Book]
}
type Book {
    id: ID
    title: String
    author: String
}

The above code block creates a GraphQL query that returns a list of books. Each book has an ID, title, and author. With GraphQL, the client can query the exact data it needs, making the API flexible and powerful.

Share

It’s Really not that Complicated.

You can actually understand what’s going on inside your live applications.

Try Lightrun’s Playground

Lets Talk!

Looking for more information about Lightrun and debugging?
We’d love to hear from you!
Drop us a line and we’ll get back to you shortly.

By submitting this form, I agree to Lightrun’s Privacy Policy and Terms of Use.