Skip to content

Commit 0e4e7d5

Browse files
hongkongkiwiclaude
andcommitted
fix: improve Prisma version resolution for pnpm workspaces
- Fix package.json resolution bug that could pick wrong package in pnpm workspaces - Add fallback to read version directly from node_modules/@prisma/client - Support workspace: protocol by extracting explicit versions - Provide helpful error messages for catalog: references - Zero new dependencies added Fixes issue where Prisma extension would select wrong version when using pnpm workspaces without explicit version in trigger.config.ts 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <[email protected]>
1 parent 59df4af commit 0e4e7d5

File tree

3 files changed

+66
-11
lines changed

3 files changed

+66
-11
lines changed

packages/build/src/extensions/prisma.ts

Lines changed: 54 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,9 @@ import { BuildManifest, BuildTarget } from "@trigger.dev/core/v3";
22
import { binaryForRuntime, BuildContext, BuildExtension } from "@trigger.dev/core/v3/build";
33
import assert from "node:assert";
44
import { existsSync } from "node:fs";
5-
import { cp, readdir } from "node:fs/promises";
5+
import { cp, readdir, readFile } from "node:fs/promises";
66
import { dirname, join, resolve } from "node:path";
7+
import { readPackageJSON, resolvePackageJSON } from "pkg-types";
78

89
export type PrismaExtensionOptions = {
910
schema: string;
@@ -102,12 +103,60 @@ export class PrismaExtension implements BuildExtension {
102103
(external) => external.name === "@prisma/client"
103104
);
104105

105-
const version = prismaExternal?.version ?? this.options.version;
106+
let version = prismaExternal?.version ?? this.options.version;
106107

108+
// If still no version, try to read from installed node_modules
107109
if (!version) {
108-
throw new Error(
109-
`PrismaExtension could not determine the version of @prisma/client. It's possible that the @prisma/client was not used in the project. If this isn't the case, please provide a version in the PrismaExtension options.`
110-
);
110+
// First, try to read the actual installed @prisma/client version
111+
const installedPrismaPath = join(context.workingDir, "node_modules", "@prisma", "client", "package.json");
112+
if (existsSync(installedPrismaPath)) {
113+
try {
114+
const installedPkg = await readPackageJSON(installedPrismaPath);
115+
if (installedPkg?.version) {
116+
version = installedPkg.version;
117+
context.logger.debug(
118+
`PrismaExtension resolved version from node_modules: ${version}`
119+
);
120+
}
121+
} catch (e) {
122+
context.logger.debug("Failed to read @prisma/client from node_modules", { error: e });
123+
}
124+
}
125+
126+
// If still no version, check for catalog/workspace references and provide helpful error
127+
if (!version) {
128+
const packageJsonPath = await resolvePackageJSON(context.workingDir);
129+
let errorDetail = "";
130+
131+
if (packageJsonPath) {
132+
const pkg = await readPackageJSON(packageJsonPath);
133+
const versionSpec = pkg.dependencies?.["@prisma/client"] ||
134+
pkg.devDependencies?.["@prisma/client"];
135+
136+
if (versionSpec?.startsWith("catalog:")) {
137+
errorDetail = `Found pnpm catalog reference "${versionSpec}". `;
138+
} else if (versionSpec?.startsWith("workspace:")) {
139+
// Handle workspace: protocol - strip prefix and use the version if it's explicit
140+
const stripped = versionSpec.replace("workspace:", "").trim();
141+
if (stripped && stripped !== "*" && stripped !== "^" && stripped !== "~") {
142+
version = stripped;
143+
context.logger.debug(
144+
`PrismaExtension resolved version from workspace protocol: ${version}`
145+
);
146+
} else {
147+
errorDetail = `Found workspace reference "${versionSpec}". `;
148+
}
149+
}
150+
}
151+
152+
if (!version) {
153+
throw new Error(
154+
`PrismaExtension could not determine the version of @prisma/client. ${errorDetail}` +
155+
`When using pnpm catalogs or workspace protocols, please provide an explicit version in the PrismaExtension options: ` +
156+
`prismaExtension({ version: "6.14.0", ... })`
157+
);
158+
}
159+
}
111160
}
112161

113162
context.logger.debug(`PrismaExtension is generating the Prisma client for version ${version}`);

packages/cli-v3/src/build/externals.ts

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -215,6 +215,17 @@ function createExternalsCollector(
215215
return undefined;
216216
}
217217

218+
// Verify we found the right package.json (not a parent workspace)
219+
if (packageJson.name !== packageName) {
220+
logger.debug("[externals][onResolve] Found package.json but name doesn't match", {
221+
expected: packageName,
222+
found: packageJson.name,
223+
packageJsonPath,
224+
external,
225+
});
226+
return undefined;
227+
}
228+
218229
if (!external.filter.test(packageJson.name)) {
219230
logger.debug("[externals][onResolve] Package name does not match", {
220231
external,

pnpm-lock.yaml

Lines changed: 1 addition & 6 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)