prisma / prisma/orm

P2016 since 2.11.0 when nested create and reference to same are within same query graph

Open
#4,367 9 comments 3 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

bug/2-confirmed kind/bug status/needs-action topic: nested write (create/update/delete) topic: order of nested operations
Dominant language
TypeScript
Stars
47.6k
Forks
2.5k
Avg merge
21h 59m
Merged PRs (30d)
95

Description

Bug description

With Prisma 2.10.0, it was possible to, within a single query graph, both create a nested record, and, make reference to the newly created record. With Prisma 2.11.0 and 2.12.0, this is broken.

How to reproduce

I created a sample on github that's based on the TypeScript 'scripts' example within the prisma-samples project.

https://github.com/pbelbin/2020-11-25-Prisma-P2016-Bug

Check out the project, at the command line, use:

npm install
npm run dev

and you will see the error being reported.

eg:

Invalid `prisma.group.create()` invocation:


  Query interpretation error. Error for binding '4': AssertionError("[Query Graph] Expected a valid parent ID to be present for a nested connect on a one-to-many relation.")
    at PrismaClientFetcher.request (./node_modules/@prisma/client/runtime/index.js:79353:15)
    at processTicksAndRejections (internal/process/task_queues.js:93:5) {
  code: 'P2016',
  clientVersion: '2.12.0',
  meta: {
    details: `Error for binding '4': AssertionError("[Query Graph] Expected a valid parent ID to be present for a nested connect on a one-to-many relation.")`
  }
}

If you like, go into the package.json and change the version of Prisma back to 2.10.0, then use:

rm -rf node_modules
npm install
npm run dev

and you will see that there is no error.

Expected behavior

There should not be an error thrown, and, the records in the database should all get created.

Prisma information

schema.prisma:

generator client {
  provider = "prisma-client-js"
}

datasource db {
  provider = "sqlite"
  url      = "file:./dev.db"
}

model Group {
  id Int @id
  name String
  
  posts Post[]
}

model Post {
  id        Int     @default(autoincrement()) @id
  title     String
  content   String?
  published Boolean @default(false)
  author    User?   @relation(fields: [authorId], references: [id])
  authorId  Int?
  
  group Group? @relation(fields: [groupId], references: [id])
  groupId Int?
}

model User {
  id    Int     @id
  email String  @unique
  name  String?
  posts Post[]
}

sample code:

import { PrismaClient } from '@prisma/client'

const prisma = new PrismaClient()

// A `main` function so that we can use async/await
async function main() {
  // Delete existing data
  await prisma.user.deleteMany({});
  await prisma.post.deleteMany({});
  await prisma.group.deleteMany({});
  
  
  // Determine high# for authorID
  const newAuthorID = 1;
  
  
  // Create 2 posts by new user
  await prisma.group.create({
    data: {
      id: 20,
      name: 'Grp1',
      posts: {
        create: [
          {
            title: 'post x-1',
            content: 'Yabba dabba do!',
            author: {
              create: {
                id: newAuthorID,
                email: 'author1@testing.com',
                name: 'Fred Flintstone',
              }
            }
          },
          {
            title: 'post x-1',
            content: 'Yabba dabba do!',
            author: {
              connect: {
                id: newAuthorID,
              }
            }
          }
        ]
      }
    }
  });
}

main()
  .catch((e) => {
    console.error(e)
    process.exit(1)
  })
  .finally(async () => {
    await prisma.$disconnect()
  })

Environment & setup

  • OS: Mac OS 11.0.1
  • Database: SQLLite, MySQL
  • Node.js version: 14.15.1
  • Prisma version:
@prisma/cli          : 2.12.0
@prisma/client       : 2.12.0
Current platform     : darwin
Query Engine         : query-engine cf0680a1bfe8d5e743dc659cc7f08009f9587d58 (at node_modules/@prisma/engines/query-engine-darwin)
Migration Engine     : migration-engine-cli cf0680a1bfe8d5e743dc659cc7f08009f9587d58 (at node_modules/@prisma/engines/migration-engine-darwin)
Introspection Engine : introspection-core cf0680a1bfe8d5e743dc659cc7f08009f9587d58 (at node_modules/@prisma/engines/introspection-engine-darwin)
Format Binary        : prisma-fmt cf0680a1bfe8d5e743dc659cc7f08009f9587d58 (at node_modules/@prisma/engines/prisma-fmt-darwin)
Studio               : 0.322.0

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Reproduce the failure from the linked sample using its package.json, schema.prisma, and the prisma.group.create() call with npm install and npm run dev; compare Prisma 2.10.0 with 2.12.0. Trace the query-graph binding error for the nested create/connect sequence. Done means the same records are created without P2016 on the affected database setups.

Written by the indexing model from the issue text.

Assessment

Tech stack
mysql, node.js, sqlite, typescript
Domain
backend, databases
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
32/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.