TypeError cryptoBrowserifyExports.randomUUID in edge function

I’m seeing this error in the logs

ug 21, 04:43:15 PM: 01J5VHQH error  [entry.netlify-edge] [auth][error] AdapterError: Read more at https://errors.authjs.dev#adaptererrorAug 21, 04:43:15 PM: 01J5VHQH error  [entry.netlify-edge] [auth][cause]: TypeError: cryptoBrowserifyExports.randomUUID is not a function
    at SQLiteText.defaultFn (file:///root/.netlify/edge-functions/entry.netlify-edge/@qwik-city-plan.js:436:9021)
    at SQLiteAsyncDialect.buildInsertQuery (file:///root/.netlify/edge-functions/entry.netlify-edge/@qwik-city-plan.js:409:40696)
    at QueryPromise.getSQL (file:///root/.netlify/edge-functions/entry.netlify-edge/@qwik-city-plan.js:409:34855)
    at QueryPromise._prepare (file:///root/.netlify/edge-functions/entry.netlify-edge/@qwik-city-plan.js:409:35067)
    at QueryPromise.get (file:///root/.netlify/edge-functions/entry.netlify-edge/@qwik-city-plan.js:409:34024)
    at createSession (file:///root/.netlify/edge-functions/entry.netlify-edge/@qwik-city-plan.js:436:10159)
    at $.<computed> (file:///root/.netlify/edge-functions/entry.netlify-edge/@qwik-city-plan.js:6:12756)
    at handleLoginOrRegister (file:///root/.netlify/edge-functions/entry.netlify-edge/@qwik-city-plan.js:392:6620)
    at eventLoopTick (ext:core/01_core.js:168:7)
    at async callback (file:///root/.netlify/edge-functions/entry.netlify-edge/@qwik-city-plan.js:397:34870)Aug 21, 04:43:15 PM: 01J5VHQH error  [entry.netlify-edge] [auth][details]: {}Aug 21, 04:43:15 PM: 01J5VHQH error  [entry.netlify-edge] [auth][error] AdapterError: Read more at https://errors.authjs.dev#adaptererrorAug 21, 04:43:15 PM: 01J5VHQH error  [entry.netlify-edge] [auth][cause]: TypeError: cryptoBrowserifyExports.randomUUID is not a function
    at SQLiteText.defaultFn (file:///root/.netlify/edge-functions/entry.netlify-edge/@qwik-city-plan.js:436:9021)

this is my site

does crypto works in edge functions?

I’m using
Turso
Dreezle
authjs
qwik

@Complugg3d This might be me exposing how little I know, having never worked with edge functions on Netlify, but you could try adding it to your external_node_modules, see:

So my file looks as follows

[build]
publish = “dist”
external_node_modules = [“crypto-browserify”]
command = “npm run build”

but yet is not working, sorry but I’m new to edge functions, am I missing something?

Possibly, but…

I know less than you do.

If that doesn’t work, then I’m personally all out of suggestions.

You’ll need to wait for someone that has a better idea of how it all works.

I found the solution, the issue was at my vite config

/**
 * This is the base config for vite.
 * When building, the adapter config is used which loads this file and extends it.
 */
import { defineConfig, type UserConfig } from "vite";
import { qwikVite } from "@builder.io/qwik/optimizer";
import { qwikCity } from "@builder.io/qwik-city/vite";
import tsconfigPaths from "vite-tsconfig-paths";
import pkg from "./package.json";

import { NodeGlobalsPolyfillPlugin } from '@esbuild-plugins/node-globals-polyfill';
import { NodeModulesPolyfillPlugin } from '@esbuild-plugins/node-modules-polyfill';

type PkgDep = Record<string, string>;
const { dependencies = {}, devDependencies = {} } = pkg as any as {
  dependencies: PkgDep;
  devDependencies: PkgDep;
  [key: string]: unknown;
};
errorOnDuplicatesPkgDeps(devDependencies, dependencies);

/**
 * Note that Vite normally starts from `index.html` but the qwikCity plugin makes start at `src/entry.ssr.tsx` instead.
 */
export default defineConfig(({ command, mode }): UserConfig => {
  return {
    plugins: [qwikCity(), qwikVite(), tsconfigPaths()],
    // This tells Vite which dependencies to pre-build in dev mode.
    optimizeDeps: {
      // Put problematic deps that break bundling here, mostly those with binaries.
      // For example ['better-sqlite3'] if you use that in server functions.
      include: [ "@auth/core" ],
      exclude: [],
      esbuildOptions: {
        plugins: [
          NodeGlobalsPolyfillPlugin({
            buffer: true,
            process: true,
          }),
          NodeModulesPolyfillPlugin(),
        ],
      },
    },

    ssr: {
      noExternal: [
        // Add '@auth/drizzle-adapter' to the noExternal list
        ...Object.keys(devDependencies),
        "@auth/drizzle-adapter",

      ],
      external: [
        ...Object.keys(dependencies),
        "crypto" // Ensure crypto is handled correctly
      ],
    },

    /**
     * This is an advanced setting. It improves the bundling of your server code. To use it, make sure you understand when your consumed packages are dependencies or dev depencies. (otherwise things will break in production)
     */
    // ssr:
    //   command === "build" && mode === "production"
    //     ? {
    //         // All dev dependencies should be bundled in the server build
    //         noExternal: Object.keys(devDependencies),
    //         // Anything marked as a dependency will not be bundled
    //         // These should only be production binary deps (including deps of deps), CLI deps, and their module graph
    //         // If a dep-of-dep needs to be external, add it here
    //         // For example, if something uses `bcrypt` but you don't have it as a dep, you can write
    //         // external: [...Object.keys(dependencies), 'bcrypt']
    //         external: Object.keys(dependencies),
    //       }
    //     : undefined,

    server: {
      headers: {
        // Don't cache the server response in dev mode
        "Cache-Control": "public, max-age=0",
      },
    },
    preview: {
      headers: {
        // Do cache the server response in preview (non-adapter production build)
        "Cache-Control": "public, max-age=600",
      },
    },
  };
});

// *** utils ***

/**
 * Function to identify duplicate dependencies and throw an error
 * @param {Object} devDependencies - List of development dependencies
 * @param {Object} dependencies - List of production dependencies
 */
function errorOnDuplicatesPkgDeps(
  devDependencies: PkgDep,
  dependencies: PkgDep,
) {
  let msg = "";
  // Create an array 'duplicateDeps' by filtering devDependencies.
  // If a dependency also exists in dependencies, it is considered a duplicate.
  const duplicateDeps = Object.keys(devDependencies).filter(
    (dep) => dependencies[dep],
  );

  // include any known qwik packages
  const qwikPkg = Object.keys(dependencies).filter((value) =>
    /qwik/i.test(value),
  );

  // any errors for missing "qwik-city-plan"
  // [PLUGIN_ERROR]: Invalid module "@qwik-city-plan" is not a valid package
  msg = `Move qwik packages ${qwikPkg.join(", ")} to devDependencies`;

  if (qwikPkg.length > 0) {
    throw new Error(msg);
  }

  // Format the error message with the duplicates list.
  // The `join` function is used to represent the elements of the 'duplicateDeps' array as a comma-separated string.
  msg = `
    Warning: The dependency "${duplicateDeps.join(", ")}" is listed in both "devDependencies" and "dependencies".
    Please move the duplicated dependencies to "devDependencies" only and remove it from "dependencies"
  `;

  // Throw an error with the constructed message.
  if (duplicateDeps.length > 0) {
    throw new Error(msg);
  }
}

hi @Complugg3d :wave:t6: thanks for reaching out! We appreciate it and thanks for writing back in and sharing that you found your solution with the community!

Cheers :partying_face: