AWS Lambda Handler Event and Context Function Error
Define the Lambda entry point function with two positional arguments: def lambda_handler(event, context): matching the configured handler name in AWS console.
Root Cause Analysis
This error occurs when Python running inside the AWS Lambda execution environment invokes the handler function configured in the function settings, but the function definition does not accept the standard two positional arguments (event and context).
1. AWS Lambda Invocation Contract
The AWS Lambda Python runtime always invokes the configured handler with exactly two arguments: the invocation payload (event, typically a dictionary) and runtime metadata (context, a LambdaContext object). If the handler is defined as def handler(): with no arguments, Python raises TypeError: handler() takes 0 positional arguments but 2 were given.
2. Handler Configuration String Mismatch
The Lambda configuration string follows the format filename.function_name (e.g. app.lambda_handler). If the file is named lambda_function.py while the setting is app.handler, invocation fails immediately with a Runtime.HandlerNotFound or ModuleNotFoundError.
3. Async Handler Execution in Python Runtime
Declaring async def lambda_handler(event, context): without running the event loop inside the handler causes Lambda to return an un-awaited coroutine object.
4. Sub-Module and Packaging Hierarchy Errors
When placing code inside src/ without an __init__.py, Lambda cannot resolve src.lambda_function.handler.
Reproduction Code (MCVE)
# **Note de reproductibilité :** Spécifique au runtime AWS Lambda.
def bad_handler():
return {'statusCode': 200}
# AWS Lambda runtime attempts to invoke with (event, context)
bad_handler({'Records': []}, object())
Solution 1: Structure the Handler with (event, context) Signature
Declare the handler accepting both event and context arguments, returning standard JSON responses.
import json
def lambda_handler(event, context):
print(f'Received event keys: {list(event.keys())}')
return {
'statusCode': 200,
'body': json.dumps({'message': 'Success'})
}
# Test invocation locally
response = lambda_handler({'key': 'value'}, None)
print(f'Lambda response: {response}')
Solution 2: Support Variable Arguments with *args and **kwargs
Use *args, **kwargs to create resilient handler functions compatible with both local testing frameworks and AWS Lambda.
def flexible_handler(*args, **kwargs):
event = args[0] if args else kwargs.get('event', {})
return {'statusCode': 200, 'body': f'Processed {len(event)} items'}
print(flexible_handler({'test': 1}, None))
A common mistake is returning non-JSON-serializable objects (such as sets, datetime objects, or raw Decimal numbers from DynamoDB) in the body field. AWS API Gateway requires body to be a string (e.g. json.dumps(payload, default=str)). Edge cases occur with scheduled CloudWatch EventBridge triggers: the event object will contain {'detail-type': 'Scheduled Event'} instead of API Gateway HTTP request headers. Always validate event keys before accessing event['queryStringParameters']. Contrast this error with KeyError: 'body', which occurs when reading expected API Gateway keys from raw S3 trigger events.