jetbridge/sst-prisma

Prisma Engine Does Not Seem to be Compatible with Lambda

Closed this issue · 4 comments

I'm not sure if I'm doing something wrong here, but when I try to run prisma within a lambda function, I'm seeing the following error:

{
    "errorType": "PrismaClientInitializationError",
    "errorMessage": "\nInvalid `prisma.user.findFirst()` invocation:\n\n\nUnable to require(`/opt/nodejs/node_modules/@prisma/engines/libquery_engine-rhel-openssl-1.0.x.so.node`).\nThe Prisma engines do not seem to be compatible with your system. Please refer to the documentation about Prisma's system requirements: https://pris.ly/d/system-requirements\n\nDetails: /opt/nodejs/node_modules/@prisma/engines/libquery_engine-rhel-openssl-1.0.x.so.node: cannot open shared object file: No such file or directory",
    "name": "PrismaClientInitializationError",
    "clientVersion": "5.1.1",
    "stack": [
        "PrismaClientInitializationError: ",
        "Invalid `prisma.user.findFirst()` invocation:",
        "",
        "",
        "Unable to require(`/opt/nodejs/node_modules/@prisma/engines/libquery_engine-rhel-openssl-1.0.x.so.node`).",
        "The Prisma engines do not seem to be compatible with your system. Please refer to the documentation about Prisma's system requirements: https://pris.ly/d/system-requirements",
        "",
        "Details: /opt/nodejs/node_modules/@prisma/engines/libquery_engine-rhel-openssl-1.0.x.so.node: cannot open shared object file: No such file or directory",
        "    at Hr.handleRequestError (/opt/nodejs/node_modules/@prisma/client/runtime/library.js:122:7272)",
        "    at Hr.handleAndLogRequestError (/opt/nodejs/node_modules/@prisma/client/runtime/library.js:122:6388)",
        "    at Hr.request (/opt/nodejs/node_modules/@prisma/client/runtime/library.js:122:6108)",
        "    at async l (/opt/nodejs/node_modules/@prisma/client/runtime/library.js:126:10298)",
        "    at async file:///var/task/backend/src/api/resolver/greeting.mjs:3849:18"
    ]
}

The interesting part is that it runs via sst dev just fine, so the only issue is with deployments.

From some online research, it seems like this might relate to OpenSSL being the wrong version?
prisma/prisma#13034

When logging process.versions within the lambda, I see the following versions:

{
  node: '18.17.1',
  acorn: '8.8.2',
  ada: '2.5.0',
  ares: '1.19.1',
  brotli: '1.0.9',
  cldr: '43.0',
  icu: '73.1',
  llhttp: '6.0.11',
  modules: '108',
  napi: '9',
  nghttp2: '1.52.0',
  openssl: '3.1.2',
  simdutf: '3.2.12',
  tz: '2023c',
  undici: '5.22.1',
  unicode: '15.0',
  uv: '1.44.2',
  uvwasi: '0.0.18',
  v8: '10.2.154.26-node.26',
  zlib: '1.2.13.1-motley'
}

So it appears that OpenSSL is actually running at 3.1.2 (maybe this makes it incompatible with libquery_engine-rhel-openssl-1.0.x.so.node).

I tried experimenting with libquery_engine-rhel-openssl-3.0.x.so.node, but received the same error. Is anyone else experiencing this issue?

I may try to find a way to downgrade OpenSSL on the lambda image somehow as well.

After even more experiments, it seems like the error message is misleading. I tried using /opt/nodejs/node_modules/@prisma/engines/FAKE-1.0.x.so.node and received the same error.

This seems to imply that the correct query engine libquery_engine-rhel-openssl-1.0.x.so.node is simply not being bundled or not being found in the deployment process.

I will try to run a few tests to determine why it's missing.

After logging the directory in the deployment, I see that the only engine available in the folder is /opt/nodejs/node_modules/@prisma/engines/libquery_engine-linux-arm64-openssl-1.0.x.so.node.

I attempted to use this as the environment path, but am still receiving the same error about "no such file or directory" existing.

    this.environment = app.local
      ? {}
      : {
          PRISMA_QUERY_ENGINE_LIBRARY:
            '/opt/nodejs/node_modules/@prisma/engines/libquery_engine-rhel-openssl-1.0.x.so.node',
        };

I'm unsure if prisma is trying to read from a different working directory or something as it should be able to locate the file the same way that I did. I will continue trying to debug the issue.

It looks like commenting out the deleteEngineCmds inside prismaLayer.ts somehow solves the issue, but then schema-engine-rhel-openssl-1.0.x is included in the bundle (which is quite large).

I have no idea why removing unrelated files would impact the libquery_engine in the deployment.

Somehow manually adding the relevant deletions to the createBundleCommand fixed the issue.

So I removed

        // delete unneeded engines
        ...deleteEngineCmds,

in favor of

        // Delete unneeded engines (they just increase bundle size)
        `rm -f ${engineDir}/schema-engine*`,
        `rm -f ${engineDir}/prisma-fmt*`,
        `rm -f ${engineDir}/introspection-engine*`,

so that my final bundle command looks like

    /** Create asset bundle in docker */
    const createBundleCommand = [
      'bash',
      '-c',
      [
        `echo "Installing ${modulesToInstallArgs}"`,
        'mkdir -p /tmp/npm && pushd /tmp/npm && HOME=/tmp npm i --no-save --no-package-lock npm@latest && popd',
        `mkdir -p ${layerDir}`,
        // Install PRISMA_DEPS
        `cd ${layerDir} && HOME=/tmp /tmp/npm/node_modules/.bin/npm install --omit dev --omit peer --omit optional ${modulesToInstallArgs}`,
        // Delete unneeded engines (they just increase bundle size)
        `rm -f ${engineDir}/schema-engine*`,
        `rm -f ${engineDir}/prisma-fmt*`,
        `rm -f ${engineDir}/introspection-engine*`,
        // Internals sux
        `rm -f ${internalsDir}/dist/libquery_engine*`,
        `rm -f ${internalsDir}/dist/get-generators/libquery_engine*`,
        `rm -rf ${internalsDir}/dist/get-generators/engines`,
        // Get rid of some junk
        `rm -rf ${engineDir}/download`,
        `rm -rf ${clientDir}/generator-build`,
        `rm -rf ${nm}/@prisma/engine-core/node_modules/@prisma/engines`,
        `rm -rf ${nm}/prisma/build/public`,
        `rm -rf ${nm}/prisma/prisma-client/src/__tests__`,
        `rm -rf ${nm}/prisma/prisma-client/generator-build`,
        `rm -rf ${nm}/@types`,
        `rm -rf ${nm}/.prisma`,
      ].join(' && '),

Not sure what the actual issue was, but this works for me.