Repository: localstack/localstack

Issue:
question: Problem with API GW<->Lambda integration: "Object of type datetime is not JSON serializable"
### Is there an existing issue for this?

- [X] I have searched the existing issues and read the documentation

### Question

Hey!
This is the first time I've used LocalStack, so maybe I'm doing something wrong, but I'm getting a 500 error when trying to invoke my lambda through API GW for no apparent reason. So, repro steps:
1. Super-simple Node lambda returning 200 and "ok" body.
2. API GW integration pointing to the lambda.
3. Everything is deployed via Terraform without issues.

However, a POST request to the lambda's endpoint results in:

```
{"errorType": "InvocationException", "errorMessage": "Object of type datetime is not JSON serializable", "stackTrace":
[" File \"/opt/code/localstack/localstack/services/awslambda/lambda_api.py\", line 739, in run_lambda\n
callback=callback,\n", " File \"/opt/code/localstack/localstack/services/awslambda/lambda_executors.py\", line 224, in
execute\n return do_execute()\n", " File \"/opt/code/localstack/localstack/services/awslambda/lambda_executors.py\",
line 214, in do_execute\n return _run(func_arn=func_arn)\n", " File
\"/opt/code/localstack/localstack/utils/cloudwatch/cloudwatch_util.py\", line 157, in wrapped\n raise e\n", " File
\"/opt/code/localstack/localstack/utils/cloudwatch/cloudwatch_util.py\", line 153, in wrapped\n result = func(*args,
**kwargs)\n", " File \"/opt/code/localstack/localstack/services/awslambda/lambda_executors.py\", line 201, in _run\n
raise e\n", " File \"/opt/code/localstack/localstack/services/awslambda/lambda_executors.py\", line 189, in _run\n
result = self._execute(func_arn, func_details, event, context, version)\n", " File
\"/opt/code/localstack/localstack/services/awslambda/lambda_executors.py\", line 1022, in _execute\n raise
InvocationException(result, log_output)\n"]}
```

Any ideas?

### Repro steps
main.tf
```
terraform {
  required_providers {
    aws = {
      source = "hashicorp/aws"
      version = "~> 3.49.0"
    }
  }
}

####################### DATA SOURCES #######################
data "aws_region" "current" {}
data "aws_caller_identity" "current" {}

####################### LOCALS #######################
locals {
  common_tags = {
    project = "samcum"
  }
}

####################### VARIABLES #######################
variable "webhook_lambda_filename" {
  type = string
  default = "../../samcum-webhook-lambda/samcum-webhook-lambda.zip"
}

####################### RESOURCES #######################
resource "aws_iam_role" "samcum_webhook_lambda_iam" {
  name = "iam_for_lambda"

  assume_role_policy = <<EOF
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Action": "sts:AssumeRole",
      "Principal": {
        "Service": "lambda.amazonaws.com"
      },
      "Effect": "Allow",
      "Sid": ""
    }
  ]
}
EOF

  tags = local.common_tags
}

resource "aws_lambda_permission" "samcum_webhook_lambda_execute_permission" {
  statement_id  = "AllowExecutionFromAPIGateway"
  action        = "lambda:InvokeFunction"
  function_name = aws_lambda_function.samcum_webhook_lambda.function_name
  principal     = "apigateway.amazonaws.com"

  source_arn = "arn:aws:execute-api:${data.aws_region.current.name}:${data.aws_caller_identity.current.account_id}:${aws_api_gateway_rest_api.samcum_rest_api.id}/*/${aws_api_gateway_method.samcum_samsara_event_method.http_method}${aws_api_gateway_resource.samcum_samsara_event_resource.path}"
}

resource "aws_lambda_function" "samcum_webhook_lambda" {
  filename = var.webhook_lambda_filename
  function_name = "samcum_webhook_lambda"
  role = aws_iam_role.samcum_webhook_lambda_iam.arn
  handler = "dist/main/lambdaHandler.lambdaHandler"
  source_code_hash = filebase64sha256(var.webhook_lambda_filename)
  runtime = "nodejs14.x"

  tags = local.common_tags
}

resource "aws_api_gateway_rest_api" "samcum_rest_api" {
  name = "samcum-api"

  tags = local.common_tags
}

resource "aws_api_gateway_resource" "samcum_samsara_event_resource" {
  path_part   = "samsara-event"
  parent_id   = aws_api_gateway_rest_api.samcum_rest_api.root_resource_id
  rest_api_id = aws_api_gateway_rest_api.samcum_rest_api.id

}

resource "aws_api_gateway_method" "samcum_samsara_event_method" {
  rest_api_id   = aws_api_gateway_rest_api.samcum_rest_api.id
  resource_id   = aws_api_gateway_resource.samcum_samsara_event_resource.id
  http_method   = "POST"
  authorization = "NONE"

}

resource "aws_api_gateway_integration" "samcum_api_webhook_lambda_integration" {
  rest_api_id             = aws_api_gateway_rest_api.samcum_rest_api.id
  resource_id             = aws_api_gateway_resource.samcum_samsara_event_resource.id
  http_method             = aws_api_gateway_method.samcum_samsara_event_method.http_method
  integration_http_method = "POST"
  type                    = "AWS_PROXY"
  uri                     = aws_lambda_function.samcum_webhook_lambda.invoke_arn

}

resource "aws_api_gateway_deployment" "samcum_rest_api_deployment" {
  rest_api_id = aws_api_gateway_rest_api.samcum_rest_api.id
  triggers = {
    redeployment = sha1(jsonencode([
    aws_api_gateway_resource.samcum_samsara_event_resource.id,
    aws_api_gateway_method.samcum_samsara_event_method.id,
    aws_api_gateway_integration.samcum_api_webhook_lambda_integration.id,
  ]))
  }

  lifecycle {
    create_before_destroy = true
  }
}

resource "aws_api_gateway_stage" "samcum_rest_api_stage" {
  deployment_id = aws_api_gateway_deployment.samcum_rest_api_deployment.id
  rest_api_id   = aws_api_gateway_rest_api.samcum_rest_api.id
  stage_name    = "prod"
}

####################### OUTPUTS #######################
output "samcum_rest_api_id" {
  value = aws_api_gateway_rest_api.samcum_rest_api.id
}

output "samcum_rest_api_deployment_stage" {
  value = aws_api_gateway_stage.samcum_rest_api_stage.stage_name
}
```

lambdaHandler.ts
```
import { APIGatewayProxyEvent, APIGatewayProxyResult } from "aws-lambda";

export const lambdaHandler = async (event: APIGatewayProxyEvent): Promise<APIGatewayProxyResult> => {
    console.log("All good!");
    return {
        statusCode: 200,
        body: JSON.stringify({message: "Hello from lambda!"})
    };
};
```

`curl --location --request GET 'http://localhost:4566/restapis/pgcmkm1bv2/prod/_user_request_/samsara-event'`
_No response_
question: Problem with API GW<->Lambda integration: "Object of type datetime is not JSON serializable"
### Is there an existing issue for this?

- [X] I have searched the existing issues and read the documentation

### Question

Hey!
This is the first time I've used LocalStack, so maybe I'm doing something wrong, but I'm getting a 500 error when trying to invoke my lambda through API GW for no apparent reason. So, repro steps:
1. Super-simple Node lambda returning 200 and "ok" body.
2. API GW integration pointing to the lambda.
3. Everything is deployed via Terraform without issues.

However, a POST request to the lambda's endpoint results in:

```
{"errorType": "InvocationException", "errorMessage": "Object of type datetime is not JSON serializable", "stackTrace":
[" File \"/opt/code/localstack/localstack/services/awslambda/lambda_api.py\", line 739, in run_lambda\n
callback=callback,\n", " File \"/opt/code/localstack/localstack/services/awslambda/lambda_executors.py\", line 224, in
execute\n return do_execute()\n", " File \"/opt/code/localstack/localstack/services/awslambda/lambda_executors.py\",
line 214, in do_execute\n return _run(func_arn=func_arn)\n", " File
\"/opt/code/localstack/localstack/utils/cloudwatch/cloudwatch_util.py\", line 157, in wrapped\n raise e\n", " File
\"/opt/code/localstack/localstack/utils/cloudwatch/cloudwatch_util.py\", line 153, in wrapped\n result = func(*args,
**kwargs)\n", " File \"/opt/code/localstack/localstack/services/awslambda/lambda_executors.py\", line 201, in _run\n
raise e\n", " File \"/opt/code/localstack/localstack/services/awslambda/lambda_executors.py\", line 189, in _run\n
result = self._execute(func_arn, func_details, event, context, version)\n", " File
\"/opt/code/localstack/localstack/services/awslambda/lambda_executors.py\", line 1022, in _execute\n raise
InvocationException(result, log_output)\n"]}
```

Any ideas?

### Repro steps
main.tf
```
terraform {
  required_providers {
    aws = {
      source = "hashicorp/aws"
      version = "~> 3.49.0"
    }
  }
}

####################### DATA SOURCES #######################
data "aws_region" "current" {}
data "aws_caller_identity" "current" {}

####################### LOCALS #######################
locals {
  common_tags = {
    project = "samcum"
  }
}

####################### VARIABLES #######################
variable "webhook_lambda_filename" {
  type = string
  default = "../../samcum-webhook-lambda/samcum-webhook-lambda.zip"
}

####################### RESOURCES #######################
resource "aws_iam_role" "samcum_webhook_lambda_iam" {
  name = "iam_for_lambda"

  assume_role_policy = <<EOF
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Action": "sts:AssumeRole",
      "Principal": {
        "Service": "lambda.amazonaws.com"
      },
      "Effect": "Allow",
      "Sid": ""
    }
  ]
}
EOF

  tags = local.common_tags
}

resource "aws_lambda_permission" "samcum_webhook_lambda_execute_permission" {
  statement_id  = "AllowExecutionFromAPIGateway"
  action        = "lambda:InvokeFunction"
  function_name = aws_lambda_function.samcum_webhook_lambda.function_name
  principal     = "apigateway.amazonaws.com"

  source_arn = "arn:aws:execute-api:${data.aws_region.current.name}:${data.aws_caller_identity.current.account_id}:${aws_api_gateway_rest_api.samcum_rest_api.id}/*/${aws_api_gateway_method.samcum_samsara_event_method.http_method}${aws_api_gateway_resource.samcum_samsara_event_resource.path}"
}

resource "aws_lambda_function" "samcum_webhook_lambda" {
  filename = var.webhook_lambda_filename
  function_name = "samcum_webhook_lambda"
  role = aws_iam_role.samcum_webhook_lambda_iam.arn
  handler = "dist/main/lambdaHandler.lambdaHandler"
  source_code_hash = filebase64sha256(var.webhook_lambda_filename)
  runtime = "nodejs14.x"

  tags = local.common_tags
}

resource "aws_api_gateway_rest_api" "samcum_rest_api" {
  name = "samcum-api"

  tags = local.common_tags
}

resource "aws_api_gateway_resource" "samcum_samsara_event_resource" {
  path_part   = "samsara-event"
  parent_id   = aws_api_gateway_rest_api.samcum_rest_api.root_resource_id
  rest_api_id = aws_api_gateway_rest_api.samcum_rest_api.id

}

resource "aws_api_gateway_method" "samcum_samsara_event_method" {
  rest_api_id   = aws_api_gateway_rest_api.samcum_rest_api.id
  resource_id   = aws_api_gateway_resource.samcum_samsara_event_resource.id
  http_method   = "POST"
  authorization = "NONE"

}

resource "aws_api_gateway_integration" "samcum_api_webhook_lambda_integration" {
  rest_api_id             = aws_api_gateway_rest_api.samcum_rest_api.id
  resource_id             = aws_api_gateway_resource.samcum_samsara_event_resource.id
  http_method             = aws_api_gateway_method.samcum_samsara_event_method.http_method
  integration_http_method = "POST"
  type                    = "AWS_PROXY"
  uri                     = aws_lambda_function.samcum_webhook_lambda.invoke_arn

}

resource "aws_api_gateway_deployment" "samcum_rest_api_deployment" {
  rest_api_id = aws_api_gateway_rest_api.samcum_rest_api.id
  triggers = {
    redeployment = sha1(jsonencode([
    aws_api_gateway_resource.samcum_samsara_event_resource.id,
    aws_api_gateway_method.samcum_samsara_event_method.id,
    aws_api_gateway_integration.samcum_api_webhook_lambda_integration.id,
  ]))
  }

  lifecycle {
    create_before_destroy = true
  }
}

resource "aws_api_gateway_stage" "samcum_rest_api_stage" {
  deployment_id = aws_api_gateway_deployment.samcum_rest_api_deployment.id
  rest_api_id   = aws_api_gateway_rest_api.samcum_rest_api.id
  stage_name    = "prod"
}

####################### OUTPUTS #######################
output "samcum_rest_api_id" {
  value = aws_api_gateway_rest_api.samcum_rest_api.id
}

output "samcum_rest_api_deployment_stage" {
  value = aws_api_gateway_stage.samcum_rest_api_stage.stage_name
}
```

lambdaHandler.ts
```
import { APIGatewayProxyEvent, APIGatewayProxyResult } from "aws-lambda";

export const lambdaHandler = async (event: APIGatewayProxyEvent): Promise<APIGatewayProxyResult> => {
    console.log("All good!");
    return {
        statusCode: 200,
        body: JSON.stringify({message: "Hello from lambda!"})
    };
};
```

`curl --location --request GET 'http://localhost:4566/restapis/pgcmkm1bv2/prod/_user_request_/samsara-event'`
_No response_


Discussion:
Hello @mwysocki87, thanks for reporting! I cannot confirm your issue, can you please check if it still persists on the :latest docker tag? I tried your terraform config and lambdaHandler.ts (did a simple typscript compile on it though), and it works as expected.
Thank you for your help!
Hey, @dfangl! I'm already using the latest version, but added the tag explicitly - didn't help;( Just wonder, maybe it's something to do with the fact that my entry point handler is nested in folders: `dist/main/lambdaHandler.lambdaHandler`. Did you put yours in the root of the zip instead? 
I did, actually. I will test with a nested entry point and report back.
@mwysocki87 
Can you please share the Version information in the log of localstack at startup? It should look like this:
LocalStack version: \<VERSION\>
LocalStack build date: \<DATE\>
LocalStack build git hash: \<COMMIT\>
> Hey, @dfangl! I'm already using the latest version, but added the tag explicitly - didn't help;( Just wonder, maybe it's something to do with the fact that my entry point handler is nested in folders: `dist/main/lambdaHandler.lambdaHandler`. Did you put yours in the root of the zip instead?

Just tested using a nested structure in the function zip, still works.
Please also keep in mind your curl command sends a get request, but you create a post method integration in your terraform config. I tested with `curl --location --request POST 'http://localhost:4566/restapis/ogjhdsw1ps/prod/_user_request_/samsara-event'`
```
LocalStack version: 0.12.15
LocalStack build date: 2021-07-13
LocalStack build git hash: 0a3d5873
```
The curl GET thing is obviously a typo;) Thanks a lot for looking into this!

PS Also, a stack trace from logs...
```
2021-07-19T15:08:33:INFO:localstack.services.awslambda.lambda_executors: Error executing Lambda "arn:aws:lambda:us-east-1:000000000000:function:samcum_webhook_lambda": Object of type datetime is not JSON serializable   File "/opt/code/localstack/localstack/services/awslambda/lambda_executors.py", line 990, in _execute
    process.run()
  File "/usr/lib/python3.7/multiprocessing/process.py", line 99, in run
    self._target(*self._args, **self._kwargs)
  File "/opt/code/localstack/localstack/services/awslambda/lambda_executors.py", line 977, in do_execute
    result = lambda_function(event, context)
  File "/opt/code/localstack/localstack/services/awslambda/lambda_api.py", line 1038, in execute
    event, context, main_file=main_file, func_details=lambda_details
  File "/opt/code/localstack/localstack/services/awslambda/lambda_executors.py", line 1053, in execute_javascript_lambda
    event_json_string = "%s" % (json.dumps(event) if event else "{}")
  File "/usr/lib/python3.7/json/__init__.py", line 231, in dumps
    return _default_encoder.encode(obj)
  File "/usr/lib/python3.7/json/encoder.py", line 199, in encode
    chunks = self.iterencode(o, _one_shot=True)
  File "/usr/lib/python3.7/json/encoder.py", line 257, in iterencode
    return _iterencode(o, 0)
  File "/usr/lib/python3.7/json/encoder.py", line 179, in default
    raise TypeError(f'Object of type {o.__class__.__name__} '
```
Hi, thanks for the additional info!
That build is already 6 days old. Since then, a massive change in the lambda executors took place, which _might_ have fixed the issue.
Can you please retry with the latest version? Please pull the localstack image using `docker pull localstack/localstack:latest`.

For reference, I use this terraform config to reproduce your issue:
```
terraform {
  required_providers {
    aws = {
      source = "hashicorp/aws"
      version = "~> 3.49.0"
    }
  }
}

provider "aws" {
  access_key                  = "mock_access_key"
  region                      = "us-east-1"
  s3_force_path_style         = true
  secret_key                  = "mock_secret_key"
  skip_credentials_validation = true
  skip_metadata_api_check     = true
  skip_requesting_account_id  = true

  endpoints {
    apigateway     = "http://localhost:4566"
    cloudformation = "http://localhost:4566"
    cloudwatch     = "http://localhost:4566"
    dynamodb       = "http://localhost:4566"
    es             = "http://localhost:4566"
    firehose       = "http://localhost:4566"
    iam            = "http://localhost:4566"
    kinesis        = "http://localhost:4566"
    lambda         = "http://localhost:4566"
    route53        = "http://localhost:4566"
    redshift       = "http://localhost:4566"
    s3             = "http://localhost:4566"
    secretsmanager = "http://localhost:4566"
    ses            = "http://localhost:4566"
    sns            = "http://localhost:4566"
    sqs            = "http://localhost:4566"
    ssm            = "http://localhost:4566"
    stepfunctions  = "http://localhost:4566"
    sts            = "http://localhost:4566"
  }
}

####################### DATA SOURCES #######################
data "aws_region" "current" {}
data "aws_caller_identity" "current" {}

####################### LOCALS #######################
locals {
  common_tags = {
    project = "samcum"
  }
}

####################### VARIABLES #######################
variable "webhook_lambda_filename" {
  type = string
  default = "function.zip"
}

####################### RESOURCES #######################
resource "aws_iam_role" "samcum_webhook_lambda_iam" {
  name = "iam_for_lambda"

  assume_role_policy = <<EOF
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Action": "sts:AssumeRole",
      "Principal": {
        "Service": "lambda.amazonaws.com"
      },
      "Effect": "Allow",
      "Sid": ""
    }
  ]
}
EOF

  tags = local.common_tags
}

resource "aws_lambda_permission" "samcum_webhook_lambda_execute_permission" {
  statement_id  = "AllowExecutionFromAPIGateway"
  action        = "lambda:InvokeFunction"
  function_name = aws_lambda_function.samcum_webhook_lambda.function_name
  principal     = "apigateway.amazonaws.com"

  source_arn = "arn:aws:execute-api:${data.aws_region.current.name}:${data.aws_caller_identity.current.account_id}:${aws_api_gateway_rest_api.samcum_rest_api.id}/*/${aws_api_gateway_method.samcum_samsara_event_method.http_method}${aws_api_gateway_resource.samcum_samsara_event_resource.path}"
}

resource "aws_lambda_function" "samcum_webhook_lambda" {
  filename = var.webhook_lambda_filename
  function_name = "samcum_webhook_lambda"
  role = aws_iam_role.samcum_webhook_lambda_iam.arn
  handler = "dist/main/lambdaHandler.lambdaHandler"
  source_code_hash = filebase64sha256(var.webhook_lambda_filename)
  runtime = "nodejs14.x"

  tags = local.common_tags
}

resource "aws_api_gateway_rest_api" "samcum_rest_api" {
  name = "samcum-api"

  tags = local.common_tags
}

resource "aws_api_gateway_resource" "samcum_samsara_event_resource" {
  path_part   = "samsara-event"
  parent_id   = aws_api_gateway_rest_api.samcum_rest_api.root_resource_id
  rest_api_id = aws_api_gateway_rest_api.samcum_rest_api.id

}

resource "aws_api_gateway_method" "samcum_samsara_event_method" {
  rest_api_id   = aws_api_gateway_rest_api.samcum_rest_api.id
  resource_id   = aws_api_gateway_resource.samcum_samsara_event_resource.id
  http_method   = "POST"
  authorization = "NONE"

}

resource "aws_api_gateway_integration" "samcum_api_webhook_lambda_integration" {
  rest_api_id             = aws_api_gateway_rest_api.samcum_rest_api.id
  resource_id             = aws_api_gateway_resource.samcum_samsara_event_resource.id
  http_method             = aws_api_gateway_method.samcum_samsara_event_method.http_method
  integration_http_method = "POST"
  type                    = "AWS_PROXY"
  uri                     = aws_lambda_function.samcum_webhook_lambda.invoke_arn

}

resource "aws_api_gateway_deployment" "samcum_rest_api_deployment" {
  rest_api_id = aws_api_gateway_rest_api.samcum_rest_api.id
  triggers = {
    redeployment = sha1(jsonencode([
    aws_api_gateway_resource.samcum_samsara_event_resource.id,
    aws_api_gateway_method.samcum_samsara_event_method.id,
    aws_api_gateway_integration.samcum_api_webhook_lambda_integration.id,
  ]))
  }

  lifecycle {
    create_before_destroy = true
  }
}

resource "aws_api_gateway_stage" "samcum_rest_api_stage" {
  deployment_id = aws_api_gateway_deployment.samcum_rest_api_deployment.id
  rest_api_id   = aws_api_gateway_rest_api.samcum_rest_api.id
  stage_name    = "prod"
}

####################### OUTPUTS #######################
output "samcum_rest_api_id" {
  value = aws_api_gateway_rest_api.samcum_rest_api.id
}

output "samcum_rest_api_deployment_stage" {
  value = aws_api_gateway_stage.samcum_rest_api_stage.stage_name
}
```

Lambdahandler is just the compiled version of yours. I adapted the terraform config to use localstack instead of aws. Please make sure your lambdaHandler returns a json as body.
Ok, I pulled the image like you suggested. This time it's:

LocalStack version: 0.12.15
2021-07-19T16:06:25:DEBUG:bootstrap.py: Executing command: docker inspect -f '{{ .Name }}' c52b7cb5aa95
LocalStack build date: 2021-07-19
LocalStack build git hash: df935f73

However, the problem persists:/ Is that the freshest build?
Hi, yes, that is the newest build currently available.
Just to be a step closer to reproduce:
Please try to deploy like this:
1. Make sure localstack is started, with a fresh state. Empty DATA_DIR and so on.
2. Make a empty new directory, with only the main.tf I posted, and your lambdaHandler.ts
3. Compile the lambdahandler with `tsc lambdaHandler.ts`, and put it in ./dist/main/.
4. Run `zip function.zip dist/main/lambdaHandler.js`
5. Run `terraform init`
6. Run `terraform apply`
7. Run the curl command `curl --location --request POST 'http://localhost:4566/restapis/<api_gw_id>/prod/_user_request_/samsara-event'`

Please also confirm: Do you use pro version of localstack, so do you set an API Key?
No, I use the community version - no API key. Does it mean I won't be able to set API key once I get past this problem?
No, I just wanted to check if our testing environments are the same :) How do you start localstack exactly? Can you share the command / docker-compose file?
You're reading my mind;)
```
version: '2.1'
services:
  localstack:
    image: localstack/localstack:latest
    ports:
      - "4566:4566"
    environment:
      - SERVICES=apigateway,lambda,sqs,cloudwatch,ssm,s3,iam,dynamodb,sts
      - DEBUG=1
    networks:
      - default
  builder:
    build: .
    links:
      - localstack
    depends_on:
      - localstack
    networks:
      - default
```
Maybe I'm missing some service?

Nah, tried without the `SERVICES` var - same issue.
Hello @mwysocki87, thanks for reporting! I cannot confirm your issue, can you please check if it still persists on the :latest docker tag? I tried your terraform config and lambdaHandler.ts (did a simple typscript compile on it though), and it works as expected.
Thank you for your help!
Hey, @dfangl! I'm already using the latest version, but added the tag explicitly - didn't help;( Just wonder, maybe it's something to do with the fact that my entry point handler is nested in folders: `dist/main/lambdaHandler.lambdaHandler`. Did you put yours in the root of the zip instead? 
I did, actually. I will test with a nested entry point and report back.
@mwysocki87 
Can you please share the Version information in the log of localstack at startup? It should look like this:
LocalStack version: \<VERSION\>
LocalStack build date: \<DATE\>
LocalStack build git hash: \<COMMIT\>
> Hey, @dfangl! I'm already using the latest version, but added the tag explicitly - didn't help;( Just wonder, maybe it's something to do with the fact that my entry point handler is nested in folders: `dist/main/lambdaHandler.lambdaHandler`. Did you put yours in the root of the zip instead?

Just tested using a nested structure in the function zip, still works.
Please also keep in mind your curl command sends a get request, but you create a post method integration in your terraform config. I tested with `curl --location --request POST 'http://localhost:4566/restapis/ogjhdsw1ps/prod/_user_request_/samsara-event'`
```
LocalStack version: 0.12.15
LocalStack build date: 2021-07-13
LocalStack build git hash: 0a3d5873
```
The curl GET thing is obviously a typo;) Thanks a lot for looking into this!

PS Also, a stack trace from logs...
```
2021-07-19T15:08:33:INFO:localstack.services.awslambda.lambda_executors: Error executing Lambda "arn:aws:lambda:us-east-1:000000000000:function:samcum_webhook_lambda": Object of type datetime is not JSON serializable   File "/opt/code/localstack/localstack/services/awslambda/lambda_executors.py", line 990, in _execute
    process.run()
  File "/usr/lib/python3.7/multiprocessing/process.py", line 99, in run
    self._target(*self._args, **self._kwargs)
  File "/opt/code/localstack/localstack/services/awslambda/lambda_executors.py", line 977, in do_execute
    result = lambda_function(event, context)
  File "/opt/code/localstack/localstack/services/awslambda/lambda_api.py", line 1038, in execute
    event, context, main_file=main_file, func_details=lambda_details
  File "/opt/code/localstack/localstack/services/awslambda/lambda_executors.py", line 1053, in execute_javascript_lambda
    event_json_string = "%s" % (json.dumps(event) if event else "{}")
  File "/usr/lib/python3.7/json/__init__.py", line 231, in dumps
    return _default_encoder.encode(obj)
  File "/usr/lib/python3.7/json/encoder.py", line 199, in encode
    chunks = self.iterencode(o, _one_shot=True)
  File "/usr/lib/python3.7/json/encoder.py", line 257, in iterencode
    return _iterencode(o, 0)
  File "/usr/lib/python3.7/json/encoder.py", line 179, in default
    raise TypeError(f'Object of type {o.__class__.__name__} '
```
Hi, thanks for the additional info!
That build is already 6 days old. Since then, a massive change in the lambda executors took place, which _might_ have fixed the issue.
Can you please retry with the latest version? Please pull the localstack image using `docker pull localstack/localstack:latest`.

For reference, I use this terraform config to reproduce your issue:
```
terraform {
  required_providers {
    aws = {
      source = "hashicorp/aws"
      version = "~> 3.49.0"
    }
  }
}

provider "aws" {
  access_key                  = "mock_access_key"
  region                      = "us-east-1"
  s3_force_path_style         = true
  secret_key                  = "mock_secret_key"
  skip_credentials_validation = true
  skip_metadata_api_check     = true
  skip_requesting_account_id  = true

  endpoints {
    apigateway     = "http://localhost:4566"
    cloudformation = "http://localhost:4566"
    cloudwatch     = "http://localhost:4566"
    dynamodb       = "http://localhost:4566"
    es             = "http://localhost:4566"
    firehose       = "http://localhost:4566"
    iam            = "http://localhost:4566"
    kinesis        = "http://localhost:4566"
    lambda         = "http://localhost:4566"
    route53        = "http://localhost:4566"
    redshift       = "http://localhost:4566"
    s3             = "http://localhost:4566"
    secretsmanager = "http://localhost:4566"
    ses            = "http://localhost:4566"
    sns            = "http://localhost:4566"
    sqs            = "http://localhost:4566"
    ssm            = "http://localhost:4566"
    stepfunctions  = "http://localhost:4566"
    sts            = "http://localhost:4566"
  }
}

####################### DATA SOURCES #######################
data "aws_region" "current" {}
data "aws_caller_identity" "current" {}

####################### LOCALS #######################
locals {
  common_tags = {
    project = "samcum"
  }
}

####################### VARIABLES #######################
variable "webhook_lambda_filename" {
  type = string
  default = "function.zip"
}

####################### RESOURCES #######################
resource "aws_iam_role" "samcum_webhook_lambda_iam" {
  name = "iam_for_lambda"

  assume_role_policy = <<EOF
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Action": "sts:AssumeRole",
      "Principal": {
        "Service": "lambda.amazonaws.com"
      },
      "Effect": "Allow",
      "Sid": ""
    }
  ]
}
EOF

  tags = local.common_tags
}

resource "aws_lambda_permission" "samcum_webhook_lambda_execute_permission" {
  statement_id  = "AllowExecutionFromAPIGateway"
  action        = "lambda:InvokeFunction"
  function_name = aws_lambda_function.samcum_webhook_lambda.function_name
  principal     = "apigateway.amazonaws.com"

  source_arn = "arn:aws:execute-api:${data.aws_region.current.name}:${data.aws_caller_identity.current.account_id}:${aws_api_gateway_rest_api.samcum_rest_api.id}/*/${aws_api_gateway_method.samcum_samsara_event_method.http_method}${aws_api_gateway_resource.samcum_samsara_event_resource.path}"
}

resource "aws_lambda_function" "samcum_webhook_lambda" {
  filename = var.webhook_lambda_filename
  function_name = "samcum_webhook_lambda"
  role = aws_iam_role.samcum_webhook_lambda_iam.arn
  handler = "dist/main/lambdaHandler.lambdaHandler"
  source_code_hash = filebase64sha256(var.webhook_lambda_filename)
  runtime = "nodejs14.x"

  tags = local.common_tags
}

resource "aws_api_gateway_rest_api" "samcum_rest_api" {
  name = "samcum-api"

  tags = local.common_tags
}

resource "aws_api_gateway_resource" "samcum_samsara_event_resource" {
  path_part   = "samsara-event"
  parent_id   = aws_api_gateway_rest_api.samcum_rest_api.root_resource_id
  rest_api_id = aws_api_gateway_rest_api.samcum_rest_api.id

}

resource "aws_api_gateway_method" "samcum_samsara_event_method" {
  rest_api_id   = aws_api_gateway_rest_api.samcum_rest_api.id
  resource_id   = aws_api_gateway_resource.samcum_samsara_event_resource.id
  http_method   = "POST"
  authorization = "NONE"

}

resource "aws_api_gateway_integration" "samcum_api_webhook_lambda_integration" {
  rest_api_id             = aws_api_gateway_rest_api.samcum_rest_api.id
  resource_id             = aws_api_gateway_resource.samcum_samsara_event_resource.id
  http_method             = aws_api_gateway_method.samcum_samsara_event_method.http_method
  integration_http_method = "POST"
  type                    = "AWS_PROXY"
  uri                     = aws_lambda_function.samcum_webhook_lambda.invoke_arn

}

resource "aws_api_gateway_deployment" "samcum_rest_api_deployment" {
  rest_api_id = aws_api_gateway_rest_api.samcum_rest_api.id
  triggers = {
    redeployment = sha1(jsonencode([
    aws_api_gateway_resource.samcum_samsara_event_resource.id,
    aws_api_gateway_method.samcum_samsara_event_method.id,
    aws_api_gateway_integration.samcum_api_webhook_lambda_integration.id,
  ]))
  }

  lifecycle {
    create_before_destroy = true
  }
}

resource "aws_api_gateway_stage" "samcum_rest_api_stage" {
  deployment_id = aws_api_gateway_deployment.samcum_rest_api_deployment.id
  rest_api_id   = aws_api_gateway_rest_api.samcum_rest_api.id
  stage_name    = "prod"
}

####################### OUTPUTS #######################
output "samcum_rest_api_id" {
  value = aws_api_gateway_rest_api.samcum_rest_api.id
}

output "samcum_rest_api_deployment_stage" {
  value = aws_api_gateway_stage.samcum_rest_api_stage.stage_name
}
```

Lambdahandler is just the compiled version of yours. I adapted the terraform config to use localstack instead of aws. Please make sure your lambdaHandler returns a json as body.
Ok, I pulled the image like you suggested. This time it's:

LocalStack version: 0.12.15
2021-07-19T16:06:25:DEBUG:bootstrap.py: Executing command: docker inspect -f '{{ .Name }}' c52b7cb5aa95
LocalStack build date: 2021-07-19
LocalStack build git hash: df935f73

However, the problem persists:/ Is that the freshest build?
Hi, yes, that is the newest build currently available.
Just to be a step closer to reproduce:
Please try to deploy like this:
1. Make sure localstack is started, with a fresh state. Empty DATA_DIR and so on.
2. Make a empty new directory, with only the main.tf I posted, and your lambdaHandler.ts
3. Compile the lambdahandler with `tsc lambdaHandler.ts`, and put it in ./dist/main/.
4. Run `zip function.zip dist/main/lambdaHandler.js`
5. Run `terraform init`
6. Run `terraform apply`
7. Run the curl command `curl --location --request POST 'http://localhost:4566/restapis/<api_gw_id>/prod/_user_request_/samsara-event'`

Please also confirm: Do you use pro version of localstack, so do you set an API Key?
No, I use the community version - no API key. Does it mean I won't be able to set API key once I get past this problem?
No, I just wanted to check if our testing environments are the same :) How do you start localstack exactly? Can you share the command / docker-compose file?
You're reading my mind;)
```
version: '2.1'
services:
  localstack:
    image: localstack/localstack:latest
    ports:
      - "4566:4566"
    environment:
      - SERVICES=apigateway,lambda,sqs,cloudwatch,ssm,s3,iam,dynamodb,sts
      - DEBUG=1
    networks:
      - default
  builder:
    build: .
    links:
      - localstack
    depends_on:
      - localstack
    networks:
      - default
```
Maybe I'm missing some service?

Nah, tried without the `SERVICES` var - same issue.

Resolving patch:
diff --git a/localstack/services/awslambda/lambda_executors.py b/localstack/services/awslambda/lambda_executors.py
--- a/localstack/services/awslambda/lambda_executors.py
+++ b/localstack/services/awslambda/lambda_executors.py
@@ -927,7 +927,7 @@ def execute_java_lambda(self, event, context, main_file, func_details=None):
     def execute_javascript_lambda(self, event, context, main_file, func_details=None):
         handler = func_details.handler
         function = handler.split(".")[-1]
-        event_json_string = "%s" % (json.dumps(event) if event else "{}")
+        event_json_string = "%s" % (json.dumps(json_safe(event)) if event else "{}")
         context_json_string = "%s" % (json.dumps(context.__dict__) if context else "{}")
         cmd = (
             "node -e 'require(\"%s\").%s(%s,%s).then(r => process.stdout.write(JSON.stringify(r)))'"


Test patch: