The Lambda function result failed validation

I’ve been working with Lambda@Edge a lot lately. Throwing compute to the edge of a CloudFront distribution is handy for things like authorizing requests. Development can be frustrating, however, with slow turnaround times for changes. Usual strategies apply, like testing with mocks, to mitigate deployment delays, but sometimes issues with integration arise that you can’t duplicate locally.

I ran into one such issue recently when implementing OpenID Connect with PingOne. My sophisticated remote debugging (read: console.log('here #1')) couldn’t set me straight. All I knew was my Lambda@Edge was calling PingOne, and my browser kept telling me:

502 ERROR
The request could not be satisfied.
The Lambda function result failed validation: The body is not a string, is not an object, or exceeds the maximum size.

Apparently, my call to PingOne was failing, but I had no idea why. And the error message wasn’t helping. I scratched my head and cursed aloud and wondered repeatedly why I’ve chosen this profession for far longer than a mature person should, until I figured out the problem. Maybe this will help someone.

I’m using JavaScript, in case you didn’t decipher that from the console.log() code above. My knees start to quiver in the absence of strong typing, so I’m that kind of old-man developer. I had set up a try/catch handler with my async and awaits, and my catch handler looked something like this:

catch (err) {
  return serverError(err);
}

The serverError function looked like this:

const serverError = (err) => {
  return {
    status: "500",
    statusDescription: "Internal Server Error",
    body: err,
  };
};

No cool-kid arrow function or old-school const correctness can change err from an object to a string, nor remind the remedial JavaScript developer (me) that I’m slapping an object, not a string, into the body of my HTTP response. The error message, had I read it instead of googling it, tried to point it out, though: “The body is not a string” (bonus points if you thought with a smirk, “Of course it’s not — it’s a temple!”). The fix:

const serverError = (err) => {
  return {
    status: "500",
    statusDescription: "Internal Server Error",
    body: JSON.stringify(err),
  };
};

Making that change allowed the real error, my PingOne issue, to come through.

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.