Netlify functions ES module error when using paths config

Netlify site: leafy-begonia-4fe4c1

I’m getting a very annoying issue when trying to call my lambda functions. I’m running a Next.js site, with a handful of backend functions.

When I call any of my functions I get this message:

{"errorType":"ReferenceError","errorMessage":"module is not defined in ES module scope\nThis file is being treated as an ES module because it has a '.js' file extension and '/var/task/package.json' contains \"type\": \"module\". To treat it as a CommonJS script, rename it to use the '.cjs' file extension.","trace":["ReferenceError: module is not defined in ES module scope","This file is being treated as an ES module because it has a '.js' file extension and '/var/task/package.json' contains \"type\": \"module\". To treat it as a CommonJS script, rename it to use the '.cjs' file extension.","    at file:///var/task/___netlify-handler.js:1:1","    at ModuleJob.run (node:internal/modules/esm/module_job:218:25)","    at async ModuleLoader.import (node:internal/modules/esm/loader:329:24)","    at async _tryAwaitImport (file:///var/runtime/index.mjs:1008:16)","    at async _tryRequire (file:///var/runtime/index.mjs:1057:37)","    at async _loadUserApp (file:///var/runtime/index.mjs:1081:16)","    at async UserFunction.js.module.exports.load (file:///var/runtime/index.mjs:1119:21)","    at async start (file:///var/runtime/index.mjs:1282:23)","    at async file:///var/runtime/index.mjs:1288:1"]}

I do not get this issue when running locally with netlify dev. Everything runs perfectly on local. I’ve tried other machines/OSs as well, it’s fine everywhere except in the deployment.

After much debugging I have reduced the issue down to be something to do with having a custom path set in the function config.

This code fails to run with the module exception:

import { type Config, type Context } from "@netlify/functions";

export const config: Config = {
    path: "/api/test",  // <------- [4] NOTE THIS LINE
};

export default async function test(req: Request, context: Context): Promise<Response> {
    await new Promise((resolve) => {
        setTimeout(resolve, 1000);
    });

    return new Response(
        JSON.stringify({
            test: "success",
            req,
            context,
        }),
    );
}

If I remove line [4] where the path is set, the issue goes away and everything works fine. I’m still exporting a config object, but without path it works.

I would just take that win and forget about the nice looking url, however many of my actual functions take advantage of path parameters (/api/user/:userId) and refactoring those out will be a massive pain at this point.

My functions are all written in typescript, and I have attempted putting in my own build system to bundle convert them to js, cjs or mjs as part of the build step, but this made no difference to the error returned. I am a little uncertain here if the deployment picks up cjs or mjs over the ts files, the docs only state that js files are preferred to ts.

I do have in my package type set to module, so it is correct about that in the error message, but this is normal for a Next.js project and my code is indeed all module based anyway.

Using Node 20 as my runtime. I don’t believe I’ve done anything unusual with any of my config. The project is based on T3 App and I’ve changed nothing much in any of the config.

I have also attempted to reuse the default netlify function path, rather than my /api/ path:

path: "/.netlify/functions/test"

But this also fails to work and gives the module error.

My suspision is that it’s something to do with the Next.js SSR handler function, but I have no control over that or ability to debug it as it’s part of the Netlify environment.

Edit: I have just tried to rewrite a function into the Next.js API format, placing it in src/pages/api/test.ts. No config export. This also returns the same error about ES modules. I can only guess that under the hood it’s doing something similar to to what I was doing in the functions folder with a path config.

1 Like

I have not run into this. I just deployed a few functions with a similar setup yesterday or day before and they worked fine. Mind sharing a reproduction repo so we can check?

Here you go. I’ve stripped out everything else but a simple homepage and the test api, and pushed to a new origin that’s public (my actual repo is private).

Exacly this code is in a branch of my main repo, and is deployed here:
https://rollback-c--leafy-begonia-4fe4c1.netlify.app/api/test

I also took that public repo I’ve linked and deployed it to a brand new site:
https://dashboard-test-case.netlify.app/api/test

Any update on this?

I have since posting also tried to create a brand new T3 App from scratch, choosing none of the addons and leaving the default configs alone. Then added the example hello world API from the Next.js docs to src/pages/api/test.ts. Then deployed to a brand new Netlify site, changing no settings, and it replicates the issue I’ve got exactly.

https://github.com/timothy-bailey-redbox/t3-dash-test
https://dainty-taiyaki-95b43a.netlify.app/api/test

I thought you were talking about native Netlify Functions. But you’re talking about Next.js API routes. It might be related to: [Bug]: ESM not supported with Netlify functions? (part 2) · Issue #1456 · netlify/next-runtime (github.com)

It effects both the Next API routes and Netlify native functions. Sorry for the confusion, I switched from native functions to the Next API as a debugging step to try to resolve the error and both have the same issue.

If I set a custom path on a native Netlify function then I get exactly the same error message as using the Next API.

I’ve used native functions with custom paths before in non-Next projects without issue, the error appears related to it being a Next project, regardless if I use native or Next syntax to write the function.

I would just use the default paths on .netlify/functions/* (which works), but it leaves me unable to use path parameters which would be a major refactor to remove at this point in my project.

Without a resolution to this I’m going to be forced to deploy elsewhere, the go live date is approaching on my project so I need a resolution soon. The bug you linked has been open for well over a year without a resolution, so I can’t say that inspires any confidence this will be resolved.

I’d need a reproduction about the original bug report where native Functions are not working.

I’ve swapped this repo over to use the native netlify functions syntax:

https://github.com/timothy-bailey-redbox/t3-dash-test
https://dainty-taiyaki-95b43a.netlify.app/api/test

This repo is a brand new T3 App with no changes or addons. The only config changes I have made is to install the @netlify/functions and netlify-cli packages.

This is happening because it’s a Next.js project, so you’re basically just affected by that mentioned bug. This issue is not specific to Netlify Functions when used natively.

This happens because /api/* currently redirects to Next.js SSR/API handler which runs into that error. If you change the path to /api2/test, that also redirects to the SSR handler due to the /* redirect rule added by the Next.js Runtime. Outside of Next.js, this issue doesn’t happen.

Yes I know it’s not specific to native functions vs Next APIs, I told you that in my replication steps, and is why I gave you examples showing both syntaxes.

I had come to the conclusion myself that it was a problem with your Next environment from the error message mentioning the ___netlify-handler.js in the stack trace, and just that I’ve used your native functions before and not had this issue.

How do I fix it? I can’t just not be inside a Next project, it’s my entire stack. Am I just stuck waiting for that years old bug to be resolved? Having API functions not working within a Next project feels like a major bug in your platform, I don’t understand how this has been unresolved for so long.

1 Like

API Functions work, not sure what gave you the idea that they don’t. A specific subset of the functionality doesn’t work. In any case, that’s being fixed in v5 which is already available to try if you want: @netlify/plugin-nextjs - npm (npmjs.com)

1 Like

Ok if you want to be pedantic about it, Netlify functions do work, in a very narrow use case, as long as I don’t want to use Next.js or don’t need to use path parameters. I can say that the Next APIs do not work at all, those just crash, which is a major part of the Next system.

Can you clarify what that linked package is and how to use it to resolve the problem? I don’t currently rely on any version of that package in my project. Can I simply install it as a dependency or does it require some configuration?

Looking through the readme for V4 has this section: https://github.com/netlify/next-runtime?tab=readme-ov-file#manually-installing-the-nextjs-runtime which I suspect is what I need to do?

I am some what tentative to have my production application using a pre-release of a major version that was only uploaded 4 days ago with ~150 downloads (according to npm).


Just to note, as we were unable to resolve this in a reasonable time frame (20 days since reporting) I have had to redeploy to Versel, where this isn’t an issue, to meet my go live date on the project. If we can resolve this I may consider migrating back, but given the hassle it’s unlikely I’ll bother, consider me a lost customer. I’ll continue to respond to this thread to help anyone else who has this issue, as from the linked bug report above I’m not alone.

hi @timothy-bailey-redbo

Looking through the readme for V4 has this section: GitHub - netlify/next-runtime: The Next.js Runtime allows Next.js to run on Netlify with zero configuration which I suspect is what I need to do?

Correct! In this case Hrishikesh was suggesting you give our new RC version 5 a try. You can do this by setting that specific version - 5.0.0-rc.1 - in your package.json. That runtime will be the future of our newly improved nextjs integration and will definitely be more robust than our V4 runtime.

Please note that you need to be on at least next 13.5 for the new runtime to work.

Let me know how that works out!

1 Like

It worked for me. I think that T3-app recently updated something as well that made this issue worse. As I had not had these sort of API crashes before.

Thanks for being active and engaging with the community. I was running a prototype on my home machine with some app I was making with some friends. Glad I can get it on Netlify now ha.

Also one thing that may help : @timothy-bailey-redbo is I changed all the .js back to .mjs and removed the module option inside package.json (These seem like recent changes with T3-App that is also helping break things)