Search code examples
amazon-web-servicesaws-lambdaboto3amazon-sagemaker

"errorMessage": "Parameter validation failed in Lambda calling SageMaker endpoint


I am trying to invoke a SageMaker enpoint from AWS Lambda using a lambda function.

This is a sample API call to the endpoint from SageMaker Studio, working as expected:

enter image description here

here's my Lambda function (inspired from documentation):

import os
import io
import boto3
import json


ENDPOINT_NAME = 'iris-autoscale-6'
runtime= boto3.client('runtime.sagemaker')

def lambda_handler(event, context):
    # print("Received event: " + json.dumps(event, indent=2))
    payload = json.loads(json.dumps(event))
    print(payload)
    
    response = runtime.invoke_endpoint(EndpointName=ENDPOINT_NAME, ContentType='application/json', Body=payload)
    print(response)
    result = json.loads(response['Body'].read().decode())
    print(result)
    
    return result

My error message:

Test Event Name
ProperTest

Response
{
  "errorMessage": "Parameter validation failed:\nInvalid type for parameter Body, value: {'sepal_length': [5.1, 4.9, 4.7, 4.6, 5], 'sepal_width': [3.5, 3, 3.2, 3.1, 3.6], 'petal_length': [1.4, 1.4, 1.3, 1.5, 1.4], 'petal_width': [0.2, 0.2, 0.2, 0.2, 0.2]}, type: <class 'dict'>, valid types: <class 'bytes'>, <class 'bytearray'>, file-like object",
  "errorType": "ParamValidationError",
  "stackTrace": [
    "  File \"/var/task/lambda_function.py\", line 17, in lambda_handler\n    response = runtime.invoke_endpoint(EndpointName=ENDPOINT_NAME, ContentType='application/json', Body=payload)\n",
    "  File \"/var/runtime/botocore/client.py\", line 386, in _api_call\n    return self._make_api_call(operation_name, kwargs)\n",
    "  File \"/var/runtime/botocore/client.py\", line 678, in _make_api_call\n    api_params, operation_model, context=request_context)\n",
    "  File \"/var/runtime/botocore/client.py\", line 726, in _convert_to_request_dict\n    api_params, operation_model)\n",
    "  File \"/var/runtime/botocore/validate.py\", line 319, in serialize_to_request\n    raise ParamValidationError(report=report.generate_report())\n"
  ]
}

Function Logs
START RequestId: 70278b9f-f75e-4ac9-a827-7ad35d162512 Version: $LATEST
{'sepal_length': [5.1, 4.9, 4.7, 4.6, 5], 'sepal_width': [3.5, 3, 3.2, 3.1, 3.6], 'petal_length': [1.4, 1.4, 1.3, 1.5, 1.4], 'petal_width': [0.2, 0.2, 0.2, 0.2, 0.2]}
[ERROR] ParamValidationError: Parameter validation failed:
Invalid type for parameter Body, value: {'sepal_length': [5.1, 4.9, 4.7, 4.6, 5], 'sepal_width': [3.5, 3, 3.2, 3.1, 3.6], 'petal_length': [1.4, 1.4, 1.3, 1.5, 1.4], 'petal_width': [0.2, 0.2, 0.2, 0.2, 0.2]}, type: <class 'dict'>, valid types: <class 'bytes'>, <class 'bytearray'>, file-like object
Traceback (most recent call last):
  File "/var/task/lambda_function.py", line 17, in lambda_handler
    response = runtime.invoke_endpoint(EndpointName=ENDPOINT_NAME, ContentType='application/json', Body=payload)
  File "/var/runtime/botocore/client.py", line 386, in _api_call
    return self._make_api_call(operation_name, kwargs)
  File "/var/runtime/botocore/client.py", line 678, in _make_api_call
    api_params, operation_model, context=request_context)
  File "/var/runtime/botocore/client.py", line 726, in _convert_to_request_dict
    api_params, operation_model)
  File "/var/runtime/botocore/validate.py", line 319, in serialize_to_request
    raise ParamValidationError(report=report.generate_report())
END RequestId: 70278b9f-f75e-4ac9-a827-7ad35d162512
REPORT RequestId: 70278b9f-f75e-4ac9-a827-7ad35d162512  Duration: 26.70 ms  Billed Duration: 27 ms  Memory Size: 128 MB Max Memory Used: 76 MB  Init Duration: 343.10 ms

Here's the policy attached to the lambda function:

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "VisualEditor0",
            "Effect": "Allow",
            "Action": "sagemaker:InvokeEndpoint",
            "Resource": "arn:aws:sagemaker:ap-south-1:<my-account-id>:endpoint/iris-autoscale-6"
        }
    ]
}

Solution

  • The issue is that your payload has invalid format. It should be one of:

    <class 'bytes'>, <class 'bytearray'>, file-like object
    

    The following should address the error (note: you may have many other issues in your code):

        payload = json.dumps(event)
        print(payload)
        
        response = runtime.invoke_endpoint(EndpointName=ENDPOINT_NAME, ContentType='application/json', Body=payload.encode())