api-platform: Graphql : Cannot return null for non-nullable field

Hello,

I’ve got a very strange problem using graphql.

When I list some Contacts (note: this is the entity used by doctrine_user_provider to check login) :

{
  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
      }
    }
  }
}

I’ve got for one contact (id 219) this error :

{
  "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...
      ]
    }
  }
}

All other Contacts are returning fine, just this one (and only this one) fails to return properly. I’ve double checked what value in db could lead to such a problem, the record seems fine, no strange data, some expected null fields, no null in not null fields…

If I query this item with the same fields, it’s all ok:

{
  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
    }
}

returns:

{
  "data": {
    "contact": {
      "_id": 219,
      "salesforceId": "obfurscated",
      "email": "obfurscated@obfurscated.fr",
      "role": "ROLE_ADMINISTRATOR",
      "passwordSent": false,
      "firstName": "obfurscated",
      "lastName": "obfurscated",
      "phone": "",
      "mobilePhone": "obfurscated",
      "function": {
        "id": "\/v2\/contact_functions\/18",
        "label": "Direction"
      },
      "contactOwner": null,
      "account": null,
      "contactTitle": {
        "salesforceId": "obfurscated"
      },
      "department": {
        "salesforceId": "obfurscated"
      },
      "lastUpstreamSync": null
    }
  }
}

If i change the field role to accept nullable :

    /**
     * @var string role
     *
     * @ORM\Column(type="string", length=60, unique=false, nullable=true)
     */
    private $role = "NO_ACCESS";

Then the list query raises no error but returns this :

{
  "data": {
    "contacts": {
      "edges": [
        // some contacts...
        {
          "node": {
            "_id": 219,
            "salesforceId": "obfurscated",
            "email": null,
            "role": null,
            "passwordSent": null,
            "firstName": null,
            "lastName": null,
            "phone": null,
            "mobilePhone": null,
            "function": null,
            "contactOwner": null,
            "account": null,
            "contactTitle": null,
            "department": null,
            "lastUpstreamSync": null
          }
        },
        // some contacts...
      ]
    }
  }
}

What could lead to such a behavior, where should I look ?

About this issue

  • Original URL
  • State: open
  • Created 6 years ago
  • Comments: 17 (1 by maintainers)

Most upvoted comments

As I understand, the essence of graphql is to get data from backend without changing it, in this case, I must change backend entities in order to get additional data in front. Makes no sense.

I found what my issue was. I have a normalizer that adds a group “get-owner” to context and my properties were missing that group. So, it is a good idea to check your normalization groups.

Same problem here.

    /**
     * @var Company|null
     *
     * @ORM\ManyToOne(targetEntity="App\Entity\Company\Company", inversedBy="invoiceGenerators")
     * @ORM\JoinColumn(name="company_id", referencedColumnName="id", nullable=true)
     *
     * @Groups({"read", "write"})
     */
    private $company;
...
node {
        id
        _id
        company {
        id
        name
...

Only company id is returned as IRI, other fields, like name is null, which is wrong.

I realized that the ClassInfoTrait is being automatically called by API-Platform, so my normalizer above is redundant.

In any case it does not solve my issue.