prisma: PANIC: called `Option::unwrap()` on a `None` value in query-engine/core/src/interpreter/query_interpreters/nested_read.rs:231:50

Bug description

Hi, I’m suddenly getting this on our Prisma server:

Thrown with args: {}
Resolver info : { prev: undefined, key: 'me', typename: 'Query' }
Model : User
Error : PrismaClientRustPanicError2 [PrismaClientRustPanicError]:
Invalid `prisma.user.findUnique()` invocation:
  PANIC: called `Option::unwrap()` on a `None` value in query-engine/core/src/interpreter/query_interpreters/nested_read.rs:231:50
This is a non-recoverable error which probably happens when the Prisma Query Engine has a panic.

How to reproduce

  1. Launch your prisma project
  2. Leave it running for ~20 hours
  3. See the above error

Expected behavior

As Douglas Adams wrote, “Dont panic!”

Prisma information

Using paljs and nexus

query { me { id } }

Environment & setup

  • OS: Linux using Docker node:16-buster
  • Database:
generator client {
  provider        = "prisma-client-js"
  previewFeatures = ["selectRelationCount", "filterJson", "referentialActions", "nApi"]
}

datasource db {
  provider = "mysql"
  url      = env("DATABASE_URL")
}
  • Node.js version: 16

Prisma Version

"@prisma/client": "2.28.0",
"prisma": "2.28.0",

About this issue

  • Original URL
  • State: closed
  • Created 3 years ago
  • Comments: 24 (9 by maintainers)

Most upvoted comments

I can reproduce this issue. Please see this repo for a small reproduction. It seems as though this Rust Panic occurs when a relationship is created using a non-unique constraint. Some connectors check for this (SQLite) but others don’t and cause a runtime error (MySQL)

Notes:

  1. When using the SQLite connector an error is thrown in the command line tooling, catching this error before it gets to production. MySQL throws no error and then the Rust engine Panics at runtime.
Error: P1012

error: Error validating: The argument `references` must refer to a unique criteria in the related model `A`. But it is referencing the following fields that are not a unique criteria: custom_id
  -->  schema.prisma:21
  1. This reproduction uses v3.11.0. In >v3.12 an opaque error is thrown in the command line tooling that is difficult to debug.
An error occured while running the seed command:
Error: Command was killed with SIGKILL (Forced termination): ts-node prisma/seed.ts

My hunches are:

  • In our express server, we have a global array of PrismaClients. Each customer has their own mysql database. Plus we have one master mysql which has the list of the customers. So in some resolvers, we even call both the master, and the customer PrismaClient.
  • There is a memory issue where you do a large query that somehow starves or corrupts the arguments for the nested_join.rs function until the node is restarted.

From what I can tell, 2.29 running without nApi is running solidly so far.

I wrote this healthcheck which correctly identifies when it has crashed:

if [ "$(curl -s http://localhost:4000/graphql -X POST -H 'content-type: application/json' --data-raw $'{"variables":{"username":"x", "password":""},"query":"mutation login($username: String!, $password: String!) { login(username:$username, password:$password) }"}' | jq -r '.errors[0].message')" == "Incorrect email or password" ]; then (echo PASS && exit 0); else (echo FAIL && exit 1); fi

And the model for this is:

export const Authentication = extendType({
  type: 'Mutation',
  definition(t) {
    t.field('login', {
      type: 'String',
      args: {
        username: nonNull(stringArg()),
        password: nonNull(stringArg()),
      },
      async resolve(_root, args: LoginInputDto, ctx: Context) {
        return <implementation details>
      },
    })

The “implementation details” basically calls this:

await prisma.user.findMany({
      where: {
        username: {
          equals: username,
        },
      },
      select: {
        id: true,
        username: true,
        password: true,
        password_algor: true,
        salt: true,
        hash: true,
        admin: true,
        locale: true,
        Company: {
          select: {
            id: true,
            admin: true,

and the model for user is

model User {
  id                           Int                            @id @default(autoincrement())
  username                     String?
  full_name                    String
<snipped, as there is 100s of lines here>
  CompanyOwner                 Company?                       @relation("owner")
  PasswordResetAuth PasswordResetAuth[]
  @@unique([id, company_id], name: "primary")
  @@index([calendar_order], name: "calendar_order")
  @@index([company_id], name: "company")
  @@index([deleted], name: "deleted")
  @@index([email], name: "email")
  @@index([full_name], name: "full_name")
  @@index([hash], name: "hash_index")
  @@index([username], name: "username")
  @@map("users")
}

I could get the mysql schema too, but why would it work for many hours then die. I would expect a schema mis-match to not work straight away, and also be citing MySQL error codes

Our complete schema is propreitary however we are willing to send this as a confidential email to you.

Thank for your help with this. I will disable nApi now and report back in a day.