Netlify function returns 500 only in production and no logs

Site name: silly-banach-737501.netlify.app

I’ve got 2 lambda functions, both read a local ‘products.json’ file.
The first one works.
The second one suddenly stopped working when I modified the JSON file. (Which was still valid and didn’t break the first function.)

The developer experience was very poor:
It worked locally and I couldn’t find a way to reproduce the problem.
In production, the function would return 500 and not much else.
The logs for my broken function would only show a spinning slash.
I tried adding console.log()s to the function but none got printed.

By looking at the git history I finally figured out that my not-broken JSON was somehow the problem, but I was in complete darkness: no logs or ways to reproduce the problem, just “500”.

Did I miss something about lambda function debugging?




My problematic function (very much inspired by this fun tutorial):

const stripe = require('stripe')(process.env.STRIPE_SECRET_KEY);
const inventory = require('./data/products.json');

exports.handler = async (event) => {

  const { sku } = JSON.parse(event.body);
  const product = inventory.find((p) => p.sku === sku);

  const session = await stripe.checkout.sessions.create({
    payment_method_types: ['card'],
    billing_address_collection: 'auto',
    shipping_address_collection: {
      allowed_countries: ['US', 'CA'],
    },
    success_url: `${process.env.URL}/success`,
    cancel_url: process.env.URL,
    line_items: [
      {
        name: product.name,
        description: product.description,
        images: [product.image],
        amount: product.amount,
        currency: product.currency,
        quantity: 1,
      },
    ],
  });

  return {
    statusCode: 200,
    body: JSON.stringify({
      sessionId: session.id,
      publishableKey: process.env.STRIPE_PUBLISHABLE_KEY,
    }),
  };
};

My first function:

const products = require('./data/products.json');

exports.handler = async () => {
  return {
    statusCode: 200,
    body: JSON.stringify(products),
  };
};
1 Like

hey there, thanks for writing in.

i’ve asked the person who knows most about functions on our team to weigh in when he gets a chance - we havent forgotten about you!

2 Likes

I’m having a very similar issue. Not reading from a config file but I have two functions, one of which isn’t loggin and returning a 500 status. Note : I also have this same repo deployed for 8 other sites, all of which work fine. I’ve tried clearing cache and re-triggering the deploy a number of times. Thanks!

Update : It’s working! (kind of) I just added a console.log statement and that seemed to trigger a rebuilding of the function (or something like that). But then when I reverted it and triggered a re-deploy, it seemed to have used the file that had already been built into Netlify’s cache (seems like smart/aggressive caching, but killin my vibe right now).

Is there a way to force the rebuild/transpiling of a lambda function without actually altering the code?

1 Like

Hi @Resto, our system does a hash on your function to check if it has changed. If it hasn’t, our system won’t deploy a new one since the previous one is identical according to the hash. You can add some whitespace or change around some code comments to change the hash. Let me know if that works for you.

@Dennis the problem is I’m using Vue.js w/the webpack compiler so it’s going to scrape out any comments or whitespace. I guess I’ll have to add an // eslint-disable comment or something and have a dummy console.log to force a hash update. Would be helpful if there was a way to force a cachebust on a specfic file. Is there? Thanks!

A comment would change the hash of your function. Does your eslint config disallow comments as well? As far as forcing a new function deploy, changing the content of the file slightly (even without any functional change) is the method. Let me know how it goes.

Yeah… I truly can’t say much because I’ve been meaning to generate a test repo to prove out what I believe I’ve felt in my live projects, but I believe something breaks when you deploy a site with site content and functions, then re-trigger a deploy from the web UI. Something disconnects in that workflow and the function no longer works correctly from the site. I should’ve written down more when it happened but I believe I was feeling this specifically with event-trigger functions rather than direct-called ones. Not sure if that fits here but that’s my 2c. I tend to follow the workflow of: always trigger a commit-based deploy when wanting to make any changes to functions or site, even if just wanting to change ENV vars in the web UI. Change them then push a new commit on the site :thinking: Just my 2c. Will be watching this thread closely.


Jon

Hmm. Builds triggered in the UI triggers a build the same way as a buildhook-triggered build would be and we don’t treat it any differently. Is the issue only with functions deployed that way? Perhaps if you run into that issue again, you can start a new topic so we can look into that specific issue?

It seems like it’s related strictly to Functions, yes. Don’t have time to dig into this any more at the moment unfortunately!

No problem, @Resto. Please get back in touch when you run in to it!

Hello, I’m having a very similar issue while using functions:

  • Reading a json file
  • works locally
  • getting a 500 in production
  • no entry in the logs

I am convinced that something is wrong with function deployment through the Netlify CLI. I did the following and the build that was triggered through a push to the repo resulted in working functions but the manual deployment through netlify deploy --prod resulted in a 500 error with no log entries:

git add .
git commit -m "cache bust"
git push origin
# At this point netlify function `comicBySlug` worked after deployment is complete
npm run generate
netlify deploy --prod
# At this point the same netlify function returned a 500 response without any log entries

Relevant part of the netlify function:

exports.handler = async (event, context) => {
  console.log("cache breaking log entry")
  console.log(event)
  // ...
  const data = await require("./ComicsData.json");
  // ...
    return {
    statusCode: 200,
    body: JSON.stringify(body)
  };
};
1 Like

I think I figured it out. It’s all caused by node version mismatch. I set the environment variable AWS_LAMBDA_JS_RUNTIME to nodejs14.x per functions docs. I was using version 16 but 14 is the highest version of node runtime netlify supports.

Then I reinstalled my local packages after switching to the same node version:

# remove existing modules
rm -rf node_modules

# change node version to `14`
nvm use 14
# re-install the packages
npm i

Then when I deployed through the CLI, it worked!

netlify deploy --prod

You should also create a .nvmrc file and put down your node version into it so if you build it on notlify through webhooks, things go smoothly:

echo 14.3.0 >> .nvmrc

If the above doesn’t work, make some changes to your functions to break the netlify cache (comments don’t count!)

2 Likes

Thanks so much for coming back and sharing this solution! Knowledge sharing is something that sets future Forums members up for success, so we appreciate it :star:

Happy building!

1 Like

I’m curious if anybody is still seeing these errors? I’m in this same situation with pretty much exactly the same details as shared above. I’ve tried following the node version mismatch steps here to no avail. Has anybody else figured out a solution?

Thanks

Edit: for more context, some of my API endpoints work just fine, but others in particular return a 500 with no logs. I’m using Next.js and Netlify’s essential nextjs plugin. These endpoints that fail receive PUT requests with large payloads, but I can’t dig in any further without logs as it all works fine locally.

Hey @ncthom,

Do you have a site where we can check?

Just adding that I just experienced the same odd behavior – 500 in production, no logs, while my local and stage versions of the function were all running fine. I followed the advice here and added a comment, which appeared to bust the Netlify cache and let the function run normally in production. A little scary that I need to check my unchanged functions to see if they are still valid though!

The only unusual thing I did recently was merge a large feature branch into main, which triggered the normal build process. Hope this can be solved.

I am currently experience this issue as well, I currently have a very basic function


const prisma = new PrismaClient()

export default async (req, context) => {
  return {
    statusCode: 200,
    body: JSON.stringify({
      message: 'OK',
    }),
  };
}

export const config = {
  path: ["/assets", "/assets/:assetId/metaProperties/:metaPropertyId"],
};

and when I hit it from https://maf-gulfstream.netlify.app/assets it returns 500 with no error logs. I think it has to do with the config because it was working before that. I changed a lot between then and now and didn’t look on my netlify app because it was working locally.

Thanks for the help

I’m getting a 200 for the mentioned URL.

In any case, you’re mixing Functions v1 and v2 syntax. You should be Returning a response and not an object. Something like:

return Response.json({
  message: 'OK'
})

Hi,

I’ve got a similar issue with the paths. I have a very basic function:

import type { Context } from '@netlify/functions'

export default async (req: Request, context: Context) => {
  return new Response('OK')
}

This works (at /.netlify/functions/test). When I update it to this:

import { Config } from '@netlify/functions'
// ...
export const config: Config = {
  path: '/api/test'
}

The function (now at /api/test; also tried other paths) returns a 500 without any details. Also nothing to see in the logs. It works via netlify dev though.

How can I debug this?

By the way: I’m deploying the function as an .mts file and in all cases the function is visible in the Netlify logging console. Just no output there.