GerritVK
GerritVK

Reputation: 325

Prisma API returns relation but client returns "cannot return null for non-nullable field.."

When I try to return fields from a one-to-many relation in Prisma client playground it returns the following error:

Cannot return null for non-nullable field DeviceConfig.device.

What in my resolver or client could be causing this?

When running the following query on the backend Prisma API playground it does return the correct data so that tells me my mutations and relationship is good.

Datamodel

type Device {
  ...
  model: String! @unique
  ...
  configs: [DeviceConfig] @relation(name: "DeviceConfigs", onDelete: CASCADE)
}

type DeviceConfig {
  id: ID! @unique
  device: Device! @relation(name: "DeviceConfigs", onDelete: SET_NULL)
  name: String!
  ...
}

Resolver

deviceConfig: async (parent, { id }, context, info) => context.prisma.deviceConfig({ id }, info)

Query

{
  deviceConfig(id:"cjqigyian00ef0d206tg116k5"){
    name
    id
    device{
      model
    }
  }
}

Result

{
  "data": null,
  "errors": [
    {
      "message": "Cannot return null for non-nullable field DeviceConfig.device.",
      "locations": [
        {
          "line": 5,
          "column": 5
        }
      ],
      "path": [
        "deviceConfig",
        "device"
      ]
    }
  ]
}

I expect the query to return the model of the device like the backend Prisma API server does Query

{
  deviceConfig(where:{id:"cjqigyian00ef0d206tg116k5"}){
    name
    id
    device{
      id
      model
    }
  }
}

Result

{
  "data": {
    "deviceConfig": {
      "name": "Standard",
      "id": "cjqigyian00ef0d206tg116k5",
      "device": {
        "id": "cjqigxzs600e60d20sdw38x7p",
        "model": "7530"
      }
    }
  }
}

Upvotes: 5

Views: 2817

Answers (2)

GerritVK
GerritVK

Reputation: 325

This forum post helped me understand some caveat around Prisma client when it comes to resolvers. Help Understanding Prisma Client’s Value Proposition

In my case I was missing the following revolvers because I thought they would be implied based on the schema relationship.

const resolvers = {
  // Relationship resolvers
  Device: {
    configs: (parent, args, context) => context.prisma.device({ id: parent.id }).configs(),
  },
  DeviceConfig: {
    device: (parent, args, context) => context.prisma.deviceConfig({ id: parent.id }).device(),
  },
  Query: {
    ...User.Query,
    ...Device.Query,
    ...DeviceConfig.Query,
  },
  Mutation: {
    ...User.Mutation,
    ...Device.Mutation,
    ...DeviceConfig.Mutation,
  },
};

Upvotes: 5

Fran Dios
Fran Dios

Reputation: 3482

I think you are mixing Prisma Bindings syntax with Prisma Client syntax.

The info object is something you pass to the bindings to return what the user is asking for. However, this feature is not available in the Prisma Client, which you seem to be using. If you need that feature then you could try Prisma Bindings.

Otherwise, modify your code to something like context.prisma.deviceConfig({ id }).device(). I think it can also accept a fragment context.prisma.deviceConfig({ id }).$fragment('fragment configWithDevice on DeviceConfig { id name device { id model } }').

Upvotes: 3

Related Questions