Repository: localstack/localstack

Issue:
bug: Error invoking lambda, expected string or bytes-like object
### Is there an existing issue for this?

- [X] I have searched the existing issues

### Current Behavior

after mounting my local stack with docker compose
creating a function with boto3
Be sure my function is well created by checking in with a BOTO3 get_function.

And trying to invoke the function with Boto3 invoke function i get an error as response

```
{
   "errorMessage":"expected string or bytes-like object",
   "errorType":"TypeError",
   "stackTrace":[
      "  File \"/opt/code/localstack/localstack/services/awslambda/lambda_api.py\", line 734, 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 535, in _execute\n    return super(LambdaExecutorReuseContainers, self)._execute(func_arn, *args, **kwargs)\n",
      "  File \"/opt/code/localstack/localstack/services/awslambda/lambda_executors.py\", line 441, in _execute\n    cmd = self.prepare_execution(func_details, environment, command)\n",
      "  File \"/opt/code/localstack/localstack/services/awslambda/lambda_executors.py\", line 497, in prepare_execution\n    container_info = self.prime_docker_container(func_details, env_vars, lambda_cwd)\n",
      "  File \"/opt/code/localstack/localstack/services/awslambda/lambda_executors.py\", line 577, in prime_docker_container\n    cmd = self.get_container_startup_command(func_details, env_vars, lambda_cwd)\n",
      "  File \"/opt/code/localstack/localstack/services/awslambda/lambda_executors.py\", line 632, in get_container_startup_command\n    lambda_cwd_on_host = Util.get_host_path_for_path_in_docker(lambda_cwd)\n",
      "  File \"/opt/code/localstack/localstack/services/awslambda/lambda_executors.py\", line 1072, in get_host_path_for_path_in_docker\n    return re.sub(r\"^%s/(.*)$\" % config.TMP_FOLDER, r\"%s/\\1\" % config.HOST_TMP_FOLDER, path)\n",
      "  File \"/usr/lib/python3.7/re.py\", line 194, in sub\n    return _compile(pattern, flags).sub(repl, string, count)\n"
   ]
}
```


The docker stack log say me pretty the same thing.

```
localstack_1  | 2021-08-16 12:25:45,422:API: 127.0.0.1 - - [16/Aug/2021 12:25:45] "POST / HTTP/1.1" 200 -
localstack_1  | 2021-08-16T12:25:45:INFO:localstack.services.awslambda.lambda_api: Error executing Lambda function arn:aws:lambda:us-east-1:000000000000:function:testlambda2: expected string or bytes-like object Traceback (most recent call last):
localstack_1  |   File "/opt/code/localstack/localstack/services/awslambda/lambda_api.py", line 734, in run_lambda
localstack_1  |     callback=callback,
localstack_1  |   File "/opt/code/localstack/localstack/services/awslambda/lambda_executors.py", line 224, in execute
localstack_1  |     return do_execute()
localstack_1  |   File "/opt/code/localstack/localstack/services/awslambda/lambda_executors.py", line 214, in do_execute
localstack_1  |     return _run(func_arn=func_arn)
localstack_1  |   File "/opt/code/localstack/localstack/utils/cloudwatch/cloudwatch_util.py", line 157, in wrapped
localstack_1  |     raise e
localstack_1  |   File "/opt/code/localstack/localstack/utils/cloudwatch/cloudwatch_util.py", line 153, in wrapped
localstack_1  |     result = func(*args, **kwargs)
localstack_1  |   File "/opt/code/localstack/localstack/services/awslambda/lambda_executors.py", line 201, in _run
localstack_1  |     raise e
localstack_1  |   File "/opt/code/localstack/localstack/services/awslambda/lambda_executors.py", line 189, in _run
localstack_1  |     result = self._execute(func_arn, func_details, event, context, version)
localstack_1  |   File "/opt/code/localstack/localstack/services/awslambda/lambda_executors.py", line 535, in _execute
localstack_1  |     return super(LambdaExecutorReuseContainers, self)._execute(func_arn, *args, **kwargs)
localstack_1  |   File "/opt/code/localstack/localstack/services/awslambda/lambda_executors.py", line 441, in _execute
localstack_1  |     cmd = self.prepare_execution(func_details, environment, command)
localstack_1  |   File "/opt/code/localstack/localstack/services/awslambda/lambda_executors.py", line 497, in prepare_execution
localstack_1  |     container_info = self.prime_docker_container(func_details, env_vars, lambda_cwd)
localstack_1  |   File "/opt/code/localstack/localstack/services/awslambda/lambda_executors.py", line 577, in prime_docker_container
localstack_1  |     cmd = self.get_container_startup_command(func_details, env_vars, lambda_cwd)
localstack_1  |   File "/opt/code/localstack/localstack/services/awslambda/lambda_executors.py", line 632, in get_container_startup_command
localstack_1  |     lambda_cwd_on_host = Util.get_host_path_for_path_in_docker(lambda_cwd)
localstack_1  |   File "/opt/code/localstack/localstack/services/awslambda/lambda_executors.py", line 1072, in get_host_path_for_path_in_docker
localstack_1  |     return re.sub(r"^%s/(.*)$" % config.TMP_FOLDER, r"%s/\1" % config.HOST_TMP_FOLDER, path)
localstack_1  |   File "/usr/lib/python3.7/re.py", line 194, in sub
localstack_1  |     return _compile(pattern, flags).sub(repl, string, count)
localstack_1  | TypeError: expected string or bytes-like object
```



### Expected Behavior

Having the lambda to run  and return me the output of my function

### How are you starting LocalStack?

With a docker-compose file

### Steps To Reproduce

build image from my app.py

app.py content:

```
import json
from time import sleep

def handler(event,context):
    #the sleep timer is just to have enougth time to see what happen when function is called
    sleep(5)
    return {
        'statusCode': 200,
        'body': json.dumps({"event":event,"message":"hello from localstack"})
            }
```

Build it and tag it locally.
`docker build -t testlambda -f Dockerfile .`

with following docker file

```
FROM public.ecr.aws/lambda/python:3.8

# Copy function code
COPY app.py ${LAMBDA_TASK_ROOT}

# Install the function's dependencies using file requirements.txt
# from your project folder.

COPY requirements.txt  .
RUN  pip3 install -r requirements.txt --target "${LAMBDA_TASK_ROOT}"

# Set the CMD to your handler (could also be done as a parameter override outside of the Dockerfile)
CMD [ "app.handler" ] 
```

_NB: try to dirrectly invoke lambda by launching my lambda image
`docker run -p 9000:8000 testlambda:latest and it works`
and query it with a curl
It works._

Create my local network on docker 
`docker network create -d bridge localstacknet`

Now launch my local stack from a docker-compose.yml as following.

```
version: '3.3'
services:
  localstack:
    image: localstack/localstack:0.12.15
    
    ports:
      - "53:53"
      - "443:443"
      - "4566-4583:4566-4583"
    environment:
      - DATA_DIR=/tmp/localstack/data
      - DEBUG=1
      - DOCKER_HOST=unix:///var/run/docker.sock
      - HOSTNAME_EXTERNAL=localstack
      - HOST_TMP_FOLDER= E:/Sources/container_Lambda/storage_localstack
      - LAMBDA_EXECUTOR=docker-reuse
      - LAMBDA_REMOVE_CONTAINERS=true
      - LAMBDA_REMOTE_DOCKER=true
      - LAMBDA_DOCKER_NETWORK= localstacknet
      - SERVICES=lambda,s3,iam,cloudwatch,dynamodb
    volumes:
      - "/var/run/docker.sock:/var/run/docker.sock"
      - "E:/Sources/container_Lambda/storage_localstack/TMP:/tmp/localstack"
    networks:
      - localstacknet
    
    privileged: true

  
networks:
  localstacknet:
    external: true
    driver : bridge
    name: localstacknet
```

use boto3 to connect to local stack and create function.

Get the error when trying to invoke








### Environment

```markdown
- OS: Windows
- LocalStack: 0.12.15
```


### Anything else?

_No response_


Discussion:
Hi @FPRM !
I sadly cannot reproduce your issue. Here are the steps / commands I used to reproduce it:
- Start localstack with the docker-compose file you provided (`docker-compose up`)
- Pack the function into a Zipfile using powershell (`Compress-Archive -Path .\app.py -DestinationPath function.zip`)
- Create the lambda function (`aws --endpoint-url=http://localhost:4566 lambda create-function --function-name test-function --runtime python3.8 --role arn:aws:iam::000000000:role/lambda-ex --handler app.handler --zip-file fileb://function.zip`)
- Invoke the lambda function (`aws --endpoint-url=http://localhost:4566 lambda invoke --function-name test-function out.txt`)
- Output: `{"body":"{\"event\": {}, \"message\": \"hello from localstack\"}","statusCode":200}`

I used Windows 10 Ver 2009 to test your issue.

Please report back if the above sequence of commands work for you, and if they do, what you do differently while deploying your lambda to help narrow down your issue. Anything, from paths to filenames etc. would help in this case. Please also include the hierarchy of your deployed zip file.

Hi @dfangl 
i use a container as lambda source.
Here is my code from Boto3 to upload

```
lambda_client = boto3.client('lambda',region_name="eu-west-1",endpoint_url='https://localhost:4566',verify=False)
response_lambda_create = lambda_client.create_function(
                                        FunctionName="testlambda",
                                       
                                        Publish=True,
                                        Handler='handler',
                                        Role= "arn:aws:iam::000000000:role/lambda-ex",
                                        Code={
                                            'ImageUri':'testlambda:latest',
                                            },
                                        Description="test" ,
                                        PackageType='Image',
                                        Runtime='python3.8',
                                        
                                    )
```


NB: 
I build the image locally so the image URI is local and doesn't comes from a remote repo

Hi!
Can you try removing the Runtime Parameter (runtime is defined by the docker image itself).
Also, running container images as Lambdas is a LocalStack Pro Feature, so it will not work without an API Key.
If you have one, please make sure it gets passed correctly to the container (as I do not see it in your docker-compose file).
Ok i think we got the point, cause the read.me let me understand that lambda whas in the free feature, and i didn't see that the image upload was in the paid version.

Maybe we should pop a change request to update the read.me to be specific on what included in the lambda free version ?

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
@@ -1215,6 +1215,10 @@ def format_windows_path(cls, path):
     @classmethod
     def docker_image_for_lambda(cls, func_details):
         runtime = func_details.runtime or ""
+        if func_details.code.get("ImageUri"):
+            LOG.warning(
+                "ImageUri is set: Using Lambda container images is only supported in LocalStack Pro"
+            )
         docker_tag = runtime
         docker_image = config.LAMBDA_CONTAINER_REGISTRY
         # TODO: remove prefix once execution issues are fixed with dotnetcore/python lambdas


Test patch: