{"id":"3dd45fd96321cca8","repo":"prisma/prisma","slug":"psl-schema-read-failed-3dd45f","errorCode":"PSL_SCHEMA_READ_FAILED","errorMessage":"Failed to read Prisma schema at \"${schemaPath}\"","messagePattern":"Failed to read Prisma schema at \"(.+?)\"","errorType":"error_code","errorClass":null,"httpStatus":null,"severity":"critical","filePath":"packages/2-sql/2-authoring/contract-psl/src/provider.ts","lineNumber":112,"sourceCode":"      });\n    },\n    async load(context) {\n      const [absoluteSchemaPath] = context.resolvedInputs;\n      if (absoluteSchemaPath === undefined) {\n        throw new InternalError(\n          'prismaContract: context.resolvedInputs is empty. The CLI config loader should populate it positional-matched with source.inputs.',\n        );\n      }\n      let schema: string;\n      try {\n        schema = await readFile(absoluteSchemaPath, 'utf-8');\n      } catch (error) {\n        const message = String(error);\n        return notOk({\n          summary: `Failed to read Prisma schema at \"${schemaPath}\"`,\n          diagnostics: [\n            {\n              code: 'PSL_SCHEMA_READ_FAILED',\n              message,\n              sourceId: schemaPath,\n            },\n          ],\n          meta: { schemaPath, absoluteSchemaPath, cause: message },\n        });\n      }\n\n      const { document, sourceFile, diagnostics: parseDiagnostics } = parse(schema);\n      const { table: symbolTable, diagnostics: symbolTableDiagnostics } = buildSymbolTable({\n        document,\n        sourceFile,\n        pslBlockDescriptors: context.authoringContributions.pslBlockDescriptors,\n      });\n\n      // Do not short-circuit on provider-level diagnostics; recovered CST can\n      // still produce interpreter diagnostics in the same response.\n      const seedDiagnostics = [","sourceCodeStart":94,"sourceCodeEnd":130,"githubUrl":"https://github.com/prisma/prisma/blob/1243cdffbec0506c595ac8fd5865fe258c336fa0/packages/2-sql/2-authoring/contract-psl/src/provider.ts#L94-L130","documentation":"During the provider `load` phase, readFile(schemaPath) threw (ENOENT, EACCES, EISDIR, etc.) and could not return the PSL source text. The diagnostic carries the raw underlying error string as its message, and the notOk result summary echoes the schema path. Interpretation never starts because there is no source to parse.","triggerScenarios":"The first resolved input in context.resolvedInputs points at a path that does not exist, is not readable by the process, or is a directory. The provider at provider.ts:104-118 catches the readFile rejection and returns notOk with this code.","commonSituations":"A typo or stale relative path in prisma-next.config.ts (e.g. `./prisma/schema.prisma` after moving the file). CI running from a different working directory so the relative path no longer resolves. Filesystem permissions / container read-only mounts. A path that resolves to a directory rather than a file.","solutions":["Verify the schema path exists on disk: `ls -la <schemaPath>` from the project root the CLI runs in.","Correct the path in prisma-next.config.ts (or the source input) to point at the actual schema file.","Check read permissions / container mount if the file exists but is unreadable.","Use an absolute path or ensure the CLI's working directory matches the config's relative-path base."],"exampleFix":"// before (prisma-next.config.ts)\nexport default defineConfig({\n  contract: { sources: [{ format: 'psl', inputs: ['./prisma/schema.prisma'] }] },\n});\n// actual file lives at ./src/contract/schema.prisma -> ENOENT\n\n// after\nexport default defineConfig({\n  contract: { sources: [{ format: 'psl', inputs: ['./src/contract/schema.prisma'] }] },\n});","handlingStrategy":"validation","validationCode":"import { access, constants } from 'node:fs/promises';\nasync function assertSchemaReadable(schemaPath: string): Promise<void> {\n  try {\n    await access(schemaPath, constants.R_OK);\n  } catch {\n    throw new Error(`Prisma schema not readable at \"${schemaPath}\". Verify the path in prisma-next.config.ts inputs and file permissions before invoking prismaContract().`);\n  }\n}","typeGuard":"const isPslSchemaReadFailed = (d: ContractSourceDiagnostic): d is ContractSourceDiagnostic & { code: 'PSL_SCHEMA_READ_FAILED' } => d.code === 'PSL_SCHEMA_READ_FAILED';","tryCatchPattern":"let result;\ntry {\n  result = await provider.load(ctx);\n} catch (e) {\n  throw new Error(`Unexpected error reading schema: ${String(e)}`);\n}\nif (!result.ok) {\n  const readFail = result.diagnostics.filter(isPslSchemaReadFailed);\n  if (readFail.length) {\n    const meta = (readFail[0] as any)?.meta;\n    throw new Error(`Cannot read schema at ${meta?.absoluteSchemaPath ?? meta?.schemaPath ?? '<unknown>'}: ${readFail[0]!.message}`);\n  }\n}","preventionTips":["Resolve the schema path from a single config source (prisma-next.config.ts inputs) and assert readability with fs.access before the build.","On network-mounted filesystems where reads can flake transiently, wrap the read in a short retry loop; for missing/permission errors, fix the path instead.","Inspect the diagnostic's meta.absoluteSchemaPath to distinguish a wrong path from a permission problem."],"tags":["filesystem","configuration","io","provider"],"analyzedSha":"1243cdffbec0506c595ac8fd5865fe258c336fa0","analyzedAt":"2026-08-01T19:42:02.087Z","schemaVersion":2}