Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

4.16.1 breaks type check #19999

Closed
darklight9811 opened this issue Jun 28, 2023 · 38 comments · Fixed by #20161
Closed

4.16.1 breaks type check #19999

darklight9811 opened this issue Jun 28, 2023 · 38 comments · Fixed by #20161
Assignees
Labels
4.16.1 bug/1-unconfirmed Bug should have enough information for reproduction, but confirmation has not happened yet. kind/bug A reported bug. kind/regression A reported bug in functionality that used to work before. team/client Issue for team Client. topic: clientExtensions topic: Next.js topic: typescript
Milestone

Comments

@darklight9811
Copy link

darklight9811 commented Jun 28, 2023

Bug description

This will probably get dismissed because I'm not currently able to strip down from our repository what exactly is causing this. But from 4.16.0 -> 4.16.1 I'm not able to use next build because something on prisma is causing a cyclic type loop that is exhausting v8 memory.

I also noticed that types in some occasions (only happened in one model) stopped working. I can't go to type definition nor autocomplete. Don't dismiss it yet, I'm trying to reproduce what's causing this. I created this bug report in case anyone has the same issue (couldn't find others) and was able to recreate it in minimal reproduction.

Rolling back to 4.16.0 fixes this issue

An example of the error thrown while type checking:

<--- Last few GCs --->

[1960:00000221C0ABAC30]    85531 ms: Mark-sweep 4048.5 (4136.9) -> 4033.6 (4138.1) MB, 1230.4 / 0.0 ms  (average mu = 0.094, current mu = 0.025) allocation failure scavenge might not succeed
[1960:00000221C0ABAC30]    86821 ms: Mark-sweep 4049.6 (4138.1) -> 4034.9 (4139.4) MB, 1236.3 / 0.0 ms  (average mu = 0.068, current mu = 0.042) allocation failure scavenge might not succeed


<--- JS stacktrace --->

FATAL ERROR: Ineffective mark-compacts near heap limit Allocation failed - JavaScript heap out of memory
- info Linting and checking validity of types . 1: 00007FF6F615B34F v8::internal::CodeObjectRegistry::~CodeObjectRegistry+123599
 2: 00007FF6F60E8CB6 v8::internal::MicrotaskQueue::GetMicrotasksScopeDepth+65206
 3: 00007FF6F60E9D8D node::OnFatalError+301
 4: 00007FF6F6A1C36E v8::Isolate::ReportExternalAllocationLimitReached+94
 5: 00007FF6F6A0694D v8::SharedArrayBuffer::Externalize+781
 6: 00007FF6F68A9F2C v8::internal::Heap::EphemeronKeyWriteBarrierFromCode+1468
 7: 00007FF6F68B6BD9 v8::internal::Heap::PublishPendingAllocations+1129
 8: 00007FF6F68B3BAA v8::internal::Heap::PageFlagsAreConsistent+2842
 9: 00007FF6F68A6809 v8::internal::Heap::CollectGarbage+2137
10: 00007FF6F68A49C0 v8::internal::Heap::AllocateExternalBackingStore+2000
11: 00007FF6F68C9546 v8::internal::Factory::NewFillerObject+214
12: 00007FF6F65FBCE5 v8::internal::DateCache::Weekday+1797
13: 00007FF6F6AAA061 v8::internal::SetupIsolateDelegate::SetupHeap+494417
14: 00000221C2DC6AD0
error Command failed with exit code 1.

How to reproduce

Expected behavior

No response

Prisma information

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

datasource db {
    provider = "postgresql"
    url      = env("DATABASE_URL")
}

Somehow I believe the extends may have something to do with this.

import { PrismaClient } from "@prisma/client"

import { env } from "@/helpers/env.mjs"

import type { Prisma} from "@prisma/client"

type PaginationArgs<Input, Output extends Record<string, any> = {}> = {
	page?: number;
	limit?: number;
	sort?: "asc" | "desc";
	order?: string;

	map?: (data: Input) => Output | Promise<Output>;
}

function getPrisma () {
	return (new PrismaClient({
		log: env.NODE_ENV === "development" ? ["error", "warn"] : ["error"],
	})).$extends({
		name: "paginate",
		model: {
			$allModels: {
				async paginate<
					T,
					Args,
					Result extends Prisma.Result<T, Args, "findMany">,
					Options extends PaginationArgs<Result[number]>,
				>(this: T, args: Prisma.Exact<Args, Omit<Prisma.Args<T, "findMany">, "cursor" | "take" | "skip">> & Options) {
					const { page = 1, limit = 25, select, where, order, sort } = (args || {}) as any

					return Promise.all([
						(this as any).findMany({
							select,
							where,
							skip: (page - 1) * limit,
							take: limit,
							...(order ? { orderBy: { [order]: sort || "asc" } } : {}),
						}).then(function (result: any) {
							return args.map ? Promise.all(result.map(args.map)) : result
						}),
						(this as any).aggregate({
							_count: { id: true },
							take: limit,
							select: { _count: true },
							where,
							skip: (page - 1) * limit,
						}).then((response: any) => ({
							page,
							pages: Math.ceil(response._count.id / limit),
							total: response._count.id,
							limit,
						})),
					]) as Promise<[
						Options["map"] extends Function ? Awaited<ReturnType<Options["map"]>>[] : Result,
						{ page: number; pages: number; total: number; limit: number },
					]>
				},
			},
		},
	})
}

const globalForPrisma = globalThis as unknown as { prisma: ReturnType<typeof getPrisma> }

export const prisma =
	globalForPrisma.prisma || getPrisma()

if (env.NODE_ENV !== "production") globalForPrisma.prisma = prisma

Environment & setup

  • OS: Windows 10
  • Database: PostgreSQL
  • Node.js version: v16.17.1

Prisma Version

prisma                  : 4.16.1
@prisma/client          : 4.16.1
Current platform        : windows
Query Engine (Node-API) : libquery-engine b20ead4d3ab9e78ac112966e242ded703f4a052c (at node_modules\@prisma\engines\query_engine-windows.dll.node)    
Migration Engine        : migration-engine-cli b20ead4d3ab9e78ac112966e242ded703f4a052c (at node_modules\@prisma\engines\migration-engine-windows.exe)
Format Wasm             : @prisma/prisma-fmt-wasm 4.16.0-66.b20ead4d3ab9e78ac112966e242ded703f4a052c
Default Engines Hash    : b20ead4d3ab9e78ac112966e242ded703f4a052c
Studio                  : 0.484.0
@darklight9811 darklight9811 added the kind/bug A reported bug. label Jun 28, 2023
@jkomyno jkomyno added bug/1-unconfirmed Bug should have enough information for reproduction, but confirmation has not happened yet. kind/regression A reported bug in functionality that used to work before. 4.16.1 topic: typescript team/client Issue for team Client. labels Jun 29, 2023
@Jolg42
Copy link
Member

Jolg42 commented Jun 29, 2023

@darklight9811 Thanks for the report, we want to look at this, we'll attempt a reproduction, in the meantime:

Which version of TypeScript are you using here?

Could you try out 4.16.2-dev.2 and 4.17.0-integration-client-extensions-fluent-api.1 and see if one of these version changes anything?

@Bjoernstjerne

This comment was marked as off-topic.

@darklight9811
Copy link
Author

darklight9811 commented Jun 30, 2023

@Jolg42

4.16.2-dev.2 removed all type properties from the methods
4.17.0-integration-client-extensions-fluent-api.1 fixed it but still breaks next type checking process

I installed everything, rerun prisma generate and restarted ts server (vscode)

@SevInf
Copy link
Contributor

SevInf commented Jun 30, 2023

@darklight9811 which Typescript version are you on? There was a bug in TS compiler 5.1.x that was fixed in 5.1.5. Could you try updating to 5.1.5 and see if it fixes this problem.

@Jolg42
Copy link
Member

Jolg42 commented Jun 30, 2023

@darklight9811 Prisma version 4.16.2 is now available, based on what you said it's unlikely that it fixes your issue, but we're interested to get an update on your problem. So if you could share what's the problem / error now (might be different). That would be great!

Also like my colleague said, please let us know which TypeScript version you are using, 5.1 has some known issues that should be fixed in 5.1.5 now.

@JoeyEamigh
Copy link

JoeyEamigh commented Jul 2, 2023

In case it helps, I have this issue with TypeScript 4.9.4 as well as 5.1.5 and Prisma 4.16.1, 4.16.2, 4.17.0-integration-client-extensions-fluent-api.1, 4.17.0-integration-client-extensions-fluent-api.2, and 4.17.0-dev.47. I am not using client extensions in my project, but from reading through 4.16.0...4.16.1 it does seem that might have something to do with it. A recursive type comes to mind since no matter how much memory I give the process (I gave it 60GB for kicks), it will eventually terminate in an OOM.

Edit: Ok, now Prisma 4.16.0 is not working in a clean repo for one project, but working in a clean repo for another project. 4.15.0 work perfectly in both. Both projects have an identical Prisma and TypeScript configuration (other than a working Prisma version clearly), and an identical engine hash. I am lost. Please point me in the right direction for how to help get more consistent results! I will try to get a repro together in a much simpler project setup in the mean time.

Please let me know if there is something I can do to help debug!

prisma                  : 4.16.2
@prisma/client          : 4.16.2
Current platform        : debian-openssl-1.1.x
Query Engine (Node-API) : libquery-engine 4bc8b6e1b66cb932731fb1bdbbc550d1e010de81 (at node_modules/@prisma/engines/libquery_engine-debian-openssl-1.1.x.so.node)
Migration Engine        : migration-engine-cli 4bc8b6e1b66cb932731fb1bdbbc550d1e010de81 (at node_modules/@prisma/engines/migration-engine-debian-openssl-1.1.x)
Format Wasm             : @prisma/prisma-fmt-wasm 4.16.1-1.4bc8b6e1b66cb932731fb1bdbbc550d1e010de81
Default Engines Hash    : 4bc8b6e1b66cb932731fb1bdbbc550d1e010de81
Studio                  : 0.484.0
Preview Features        : fullTextSearch

(not sure why the engine is defaulting to openssl1.1 on Arch but no idea how to tell it to prefer 3.x)

@JoeyEamigh
Copy link

JoeyEamigh commented Jul 2, 2023

I cannot seem to make a simple reproduction, unfortunately. The issue seems to be very specific to how Prisma is being used, because I have two identical Nest.js projects in my monorepo, each importing Prisma from the same prisma.service.ts file, and the issue only occurs in one of the projects. The other project is able to build perfectly fine.

I have run some tsc profiling on identical projects, one running 4.15.0 and the other running 4.16.2. Hopefully these are somewhat helpful.

successful builds:

prisma                  : 4.15.0
@prisma/client          : 4.15.0
Current platform        : debian-openssl-1.1.x
Query Engine (Node-API) : libquery-engine 8fbc245156db7124f997f4cecdd8d1219e360944 (at ../../node_modules/@prisma/engines/libquery_engine-debian-openssl-1.1.x.so.node)
Migration Engine        : migration-engine-cli 8fbc245156db7124f997f4cecdd8d1219e360944 (at ../../node_modules/@prisma/engines/migration-engine-debian-openssl-1.1.x)
Format Wasm             : @prisma/prisma-fmt-wasm 4.15.0-28.8fbc245156db7124f997f4cecdd8d1219e360944
Default Engines Hash    : 8fbc245156db7124f997f4cecdd8d1219e360944
Studio                  : 0.484.0
Preview Features        : fullTextSearch

failing builds:

prisma                  : 4.16.2
@prisma/client          : 4.16.2
Current platform        : debian-openssl-1.1.x
Query Engine (Node-API) : libquery-engine 4bc8b6e1b66cb932731fb1bdbbc550d1e010de81 (at ../../node_modules/@prisma/engines/libquery_engine-debian-openssl-1.1.x.so.node)
Migration Engine        : migration-engine-cli 4bc8b6e1b66cb932731fb1bdbbc550d1e010de81 (at ../../node_modules/@prisma/engines/migration-engine-debian-openssl-1.1.x)
Format Wasm             : @prisma/prisma-fmt-wasm 4.16.1-1.4bc8b6e1b66cb932731fb1bdbbc550d1e010de81
Default Engines Hash    : 4bc8b6e1b66cb932731fb1bdbbc550d1e010de81
Studio                  : 0.484.0
Preview Features        : fullTextSearch

the rest of the projects are identical. the attached trace files can be thrown into https://ui.perfetto.dev/, and the resolutions.txt file is just the stdout and stderr of the following command:

NODE_OPTIONS='--max-old-space-size=61440' yarn tsc --traceResolution -p apps/api/tsconfig.app.json --generateTrace dist/debug --incremental false 2>&1 | tee ./dist/debug/resolutions.txt

4.15.0-trace.json.txt - success ~4s
4.15.0-resolutions.txt - success ~4s

4.16.2-trace.json.txt - fail ~70s
4.16.2-resolutions.txt - fail ~70s

Can probably remove the Next.js tag since this is also happening with Nest.js (these two are too closely named lol). I wish I could be more helpful than this, but tsc is proving to be a bit of a black box for debugging without any internal knowledge.

@benjaminwaterlot
Copy link

Just encountered the same problem, but interestingly enough, it's only happening in 4.16.2.
Downgrading to 4.16.1 fixes the problem.

The local build will have a memory leak until it crashes, and CI on Vercel crashes too with the same errors shared above.

I've got two similar Next.js projects and only one has the problem ; each one using typescript 5.1.6.

I can send you my prisma schemas if it's useful (would just prefer not doing it publicly here).

@Jolg42
Copy link
Member

Jolg42 commented Jul 3, 2023

@benjaminwaterlot Please send us your schema at schemas at prisma.io, so we can try it out, also:

  • Do you use any Client extension, maybe? If you could share that as well, it would be great!
  • Can you tell what are the differences between the working and failing project?
  • Ideally, if you could send us a minimal reproduction it would be the best, if feasible.

Thank you!

@millsp
Copy link
Member

millsp commented Jul 4, 2023

Hey @darklight9811 I was not able to reproduce the crash with your extension, however I did notice that the TS server freezes completely. I took your extension apart and noticed that using Exact is causing a huge slowdown, please replace it with const if you can, that would be a considerable improvement already.

That said, the reported crash is probably related to something else and is schema specific, please send us your schema (you can post it here, or via a DM on our public slack, or at schemas@prisma.io), thanks.

Details
const prisma = new PrismaClient().$extends({
    model: {
        $allModels: {
            async paginate<T, const A extends Prisma.Args<T, "findMany">, R extends Prisma.Result<T, A, "findMany">, Options extends PaginationArgs<R[number]>>(
                this: T, args: Omit<A, "cursor" | "skip" | "take"> & Options
            ) {
                return {} as Promise<[
                    Options["map"] extends Function ? Awaited<ReturnType<Options["map"]>>[] : R,
                    { page: number; pages: number; total: number; limit: number },
                ]>
            }
        }
    }
})

await prisma.user.paginate({ page: 1, limit: 10, sort: "asc", order: "id" })

@TarsiSurdi
Copy link

TarsiSurdi commented Jul 5, 2023

I'm also experiencing similar issues with Typescript when trying to annotate a method of a repository in a NestJS app using 4.16.x.

When annotating the method and it's parameter with these (from PrismaClient):
image

  1. My LSP immediately stops working and doesn't come back even after restarting;
  2. Nest is unable to compile but keeps on trying until the it errors with a memory leak similar to OP's.

However, downgrading to 4.15.0 fixes all of these issues because the types generated by the ORM are different (they do not include <ExtArgs>), so maybe it could be something related to that 🤔

@JoeyEamigh
Copy link

This is a great find! I am also using similar annotations in projects where Prisma is broken. I tend to extend Prisma.[model]IncludeArgs with a generic to get accurate function type outputs. I think that find narrows this down a lot.

@millsp
Copy link
Member

millsp commented Jul 5, 2023

@TarsiSurdi @JoeyEamigh could you please share an example of what you are doing?

@TarsiSurdi
Copy link

TarsiSurdi commented Jul 5, 2023

@millsp Of course I can! Here is the repository for the personal project I've been developing where this bug is present: fincheck-api

Please note that I've set the Prisma version to be 4.15.0 in package.json so my project doesn't show this behavior!

The issue caused by the type annotations of the findMany method inside of the BankAccountRepository class necessary for proper TypeScript/InteliSense when using it inside the BankAccountsService class as described in this image:

image

EDIT: I should clarify that the reason for the type annotations of that particular method (generics in findMany) is different that the others present in the repository is so that TypeScript is able to compile the BankAccountService's code since it uses{includes: ...} on it's query. If you don't annotate it like that, proper types are not infered for what is present in the Transaction entity.

EDIT: I've tested multiple version of TypeScript (including 5.x.x) and Node.js. The issue persists.

Steps to reproduce bug

  1. Clone the repository and set up a PostgreSQL database along with the necessary environment variables documented in the .env.example file.
  2. Before running yarn install, make sure you change the Prisma version to one of the affected by this issue and then install dependencies.
  3. (Not sure if it's necessary) Run yarn prisma generate.
  4. Try to annotate the affected method BankAccountsRepository.findMany so it's signature matches the types present on the Prisma Client generated types.
  5. Watch your TypeScript LSP die, have Nest.js to be stuck compiling until it crashes due to a memory leak of sorts...

@JoeyEamigh
Copy link

This appears to be exactly what I am doing as well. I am glad someone is facing this in a public repository. Thank you @TarsiSurdi!

@TarsiSurdi
Copy link

TarsiSurdi commented Jul 5, 2023

I look forward to getting this solved! Prisma is such a great ORM 🔥

Also, I didn't think it through but you might not even need to provide my API a database and environment variables to reproduce the issue since the server can't even compile on Prisma 4.16.x

@davidcomen
Copy link

Having the same issue with prisma 4.16.2 and typescript 5.1.6

@jasonmacdonald
Copy link

Same issue here, VSCode dies from tsserver.js getting caught in an infinite loop. I am using extensions to add a computed property to a model. If I remove the computed property, things return to normal. Still, it seems types with extensions are generally very finicky, as this is not the only instance I'm running into this issue when I'm trying to type extensions with NestJS safely.

It's probably worth noting that all of us appear to be using NestJS as well, so I'm sure that also plays a part with typing, as we cannot define types properly for extensions without proxy/factory trickery.

@millsp
Copy link
Member

millsp commented Jul 11, 2023

Hey everyone! I have been working on a fix. Based on the reproductions of @darklight9811 and @TarsiSurdi (thanks for providing these!) I was able to come up with a fix. We want to make sure that this works for you, so could you please take a moment to try the fix/branch?

I'd appreaciate if you could install @prisma/client@5.1.0-integration-fix-client-oom-default-selection.3 and prisma@5.1.0-integration-fix-client-oom-default-selection.3 in your project and let me know how it went. Thanks.

@luisrudge
Copy link

@millsp will we have a fix for the 4.x version? It's kinda hard to test this if I need to do a major upgrade at the time time

@millsp
Copy link
Member

millsp commented Jul 11, 2023

I could release a branch version based on 4.16.x if you want, but it is likely this fix will officially make it into v5.

@chunkerchunker
Copy link

I had the same problem, and @prisma/client@5.1.0-integration-fix-client-oom-default-selection.3 fixes it for me. Thanks!

@millsp
Copy link
Member

millsp commented Jul 11, 2023

For NestJS users: you will notice that we have a breaking change in Prisma 5, with beforeExit not existing anymore. You should be able to remove the enableShutdownHooks which is documented in NestJS' docs. If you need to emit queries before the shutdown, you should now use the standard NestJS way of doing it (eg. via beforeApplicationShutdown). We will work in the coming days to update the docs, you can track our process here: #20171

@Jolg42 Jolg42 added this to the 5.1.0 milestone Jul 19, 2023
@htnhan-alpha
Copy link

htnhan-alpha commented Jul 21, 2023

image

prisma ver: 5.1.0-dev.55
ts ver :5.1.6
still crash on build when using typeof operation in client

@luisrudge
Copy link

@htnhan-alpha did you try with release @prisma/client@5.1.0-integration-fix-client-oom-default-selection.3 like @millsp said?

@millsp
Copy link
Member

millsp commented Jul 21, 2023

@luisrudge did that work for you?

@luisrudge
Copy link

@millsp I couldn't test it yet because I didn't find time to upgrade to v5. We just migrated from mongo+mongoose to prisma+pgsql at work 😅 so I didn't want to risk the migration with a major upgrade. I'll try to find some time next week.

@luisrudge
Copy link

luisrudge commented Jul 21, 2023

@millsp seems to be working

5.1.0-integration-fix-client-oom-default-selection.3:
image

with v5 I get error in the id property

@millsp
Copy link
Member

millsp commented Jul 21, 2023

Thanks for reporting back!

@luisrudge
Copy link

Something pretty interesting happened...

  • I upgraded from 4.16.1 to 5.0.0 to make sure everything was still working
  • I saw the errors in the .id property and lots of other type errors because of our usage of extensions
  • I installed 5.1.0-integration-fix-client-oom-default-selection.3
  • Errors went away
  • I reinstalled 5.0.0
  • No errors on 5.0.0
  • rm -rf node_modules && yarn install
  • No errors on 5.0.0

No idea what's going on. probably a cache issue?

$ cat node_modules/@prisma/client/package.json 
{
  "name": "@prisma/client",
  "version": "5.0.0",

@millsp
Copy link
Member

millsp commented Jul 21, 2023

Perhaps, yes. Have you re-generated your client between each main step?

@luisrudge
Copy link

yeah, forgot to add that to the list 😅 but it's alright. what matters is that it failed on 5.0.0 and then it got fixed with your patch.

@luisrudge
Copy link

@millsp one thing that is still happening is that I'm not able to go to definition on the prisma methods:
image

image image

seems like the type returned from the $extends method is different

@millsp
Copy link
Member

millsp commented Jul 21, 2023

Yes, that is expected (at least on our end), the extended clients are now fully dynamic (for performance reasons). So the type and the method are somewhat "virtual" and calculated on the spot. I am curious to know about this, why do you need to go to the definition? (asking so that I can see what can be improved).

@luisrudge
Copy link

this is a repository method:
image

I want to get the actual type of the where and data.

In v4, this worked: data: Prisma.ActivityCreateInput | Prisma.ActivityUncheckedCreateInput; but now it doesn't work anymore. It was a bad practice anyway, so I decided to replace by whatever the actual prisma method expects, but I can't use that type as I always get never as type

@millsp
Copy link
Member

millsp commented Jul 21, 2023

It happens that we have introduced helpers that do exactly this. You could do Prisma.Args<typeof db.activity, 'update'>['where'] (also works on extended clients). Leaving the conversation here not to pollute the thread, feel free to ping/DM me on slack if you need any help.

@millsp
Copy link
Member

millsp commented Jul 21, 2023

Thanks for your reproduction @TarsiSurdi, I can confirm that your project can now compile with the fix I have shared.

@millsp
Copy link
Member

millsp commented Jul 22, 2023

(Maybe related #20308)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
4.16.1 bug/1-unconfirmed Bug should have enough information for reproduction, but confirmation has not happened yet. kind/bug A reported bug. kind/regression A reported bug in functionality that used to work before. team/client Issue for team Client. topic: clientExtensions topic: Next.js topic: typescript
Projects
None yet
Development

Successfully merging a pull request may close this issue.