Using unions and interfaces and end up with non-nullable field not present


I’m wondering if what i came across is a normal behaviour or a bug. Let’s say I have the following schema:

interface EntityInBoxInterface {
    id: ID!
    name: String! @search(by: [term])
type Object implements EntityInBoxInterface {
    data: String
type Face implements EntityInBoxInterface {
    data: String
    nose: Int! @search  # nose position or something like that
union EntityInBox = Object | Face
type Box
    id: ID!
    entity: EntityInBox!
    x0: Float! @search
    y0: Float! @search
    x1: Float! @search
    y1: Float! @search

Field ‘nose’ is non nullable in type ‘Face’. However, the below mutation (without ‘nose’) works:

curl --request POST \
  --url http://localhost:8080/graphql \
  --header 'Content-Type: application/json' \
  --data '{"query":"mutation {\n   addBox ( input: {\n  x0: 1.0, x1: 2.0, y0: 3.0, y1: 4.0, entity: { faceRef: { name: \"someface\"} }\n   })\n   {numUids}\n}"}'

and I end up with the ‘Face’ node without ‘nose’. Then the below query

curl --request POST
     --url localhost:8080/graphql
     --header 'Content-Type: application/json'
     --data '{"query":"query {\n  queryFace(first:10)\n  {\n  id\n nose\n  }\n}"}' | python3 -m json.tool

returns the error message - “Non-nullable field ‘nose’ (type Int!) was not present in result from Dgraph. GraphQL error propagation triggered.”
Is it meant to work like this?

i’m running dgraph locally in a docker using the following command:

sudo docker run -it -d  -p  8080:8080   dgraph/standalone:master


Hi! I would say this is the expected behaviour. In your mutation you only pass the field name in your field entity which is of union type EntityInBox. Since nose is missing your typename resolves to type Object instead of Face.

But I could be mistaken of course!

Thanks for reply!

but i really think that the mutation creates a node of type ‘Face’. Basically because the following aggregateFace query returns count 1

curl --request POST   --url localhost:8080/graphql   --header 'Content-Type: application/json'   --data '{"query":"query {\n  aggregateFace(filter:{})\n  {count}\n}"}' | python3 -m json.tool

i’m new to graphql so could be that i’m not getting it at all…

I’m not sure about this. I think it creates both, the Object AND the Face node since there is a union type. Try to query Box and resolve for __typename, I’d be curious what that would be?

I did query it with __typename. The entity in the box type is indeed ‘Face’. Also i ran aggregateObject and it shows count 0.

So I guess the problem is that the mutation with faceRef should have failed in the first place since the field nose is mandatory. I guess the input type for the mutation addBox (and especially faceRef) does say otherwise?

1 Like

correct. The mutation should fail as some mandatory fields are not being provided. But it all seems to work i.e. nodes get created. Not sure what you mean by ‘input type for the mutation’ ? How do you want me to modify the above queries to see that ?


I don’t think you need to modify anything, I think the @core-devs need to confirm this bug and add it to their list to fix.

I was encountered another bug related to union but it was ignored.

1 Like

You cannot alter the schema which gets generated by Dgraph but you could check the input type which gets created by Dgraph. Just use the explorer tab in the GraphQL area on Dgraph Cloud and look for the Query Name. Then I guess you input type is called something like AddBoxInput. Click on it and check the fields.

It seems like @pshaddel has encountered a similar problem and it seems like a bug! Maybe you should consider submitting a ticket to the support team for that!

1 Like