Invoke a Lambda Synchronously and Read the Response
Use aws lambda invoke with a payload, decode base64 logs, and pretty-print the response with jq. Full debug loop in one command.
aws lambda invoke triggers a Lambda function from the CLI and returns its response. With --log-type Tail you also get the last 4KB of execution logs base64-encoded. This is the canonical "test my function from the terminal" command — drop the payload, read the response, debug live.
Tested on AWS CLI v2.17.
When to Use This
- Testing a Lambda after a deploy without going to the console
- Reproducing a production failure with a specific payload
- Triggering a background job manually for one-off needs
- Smoke-testing a function from a CI pipeline after deployment
Don't use this when you need load testing (use a real load tool like hey or k6 against the API Gateway URL) or when you need cold-start metrics (the CLI doesn't expose timing breakdowns).
Code
# Basic invoke with a JSON payload from a file
aws lambda invoke \
--function-name my-function \
--payload file://event.json \
--cli-binary-format raw-in-base64-out \
/tmp/response.json
# Read the response
cat /tmp/response.json | jq
# Invoke and capture the last 4KB of logs at once
aws lambda invoke \
--function-name my-function \
--payload file://event.json \
--cli-binary-format raw-in-base64-out \
--log-type Tail \
/tmp/response.json \
| jq -r '.LogResult' \
| base64 --decodeThe --cli-binary-format raw-in-base64-out flag is the AWS CLI v2 quirk you can't skip — without it, the CLI base64-encodes your already-text payload, which Lambda then can't parse. Add it once and forget.
Usage
A debug script that invokes, prints both response and logs, and fails on errors:
#!/usr/bin/env bash
set -euo pipefail
FUNCTION="${1:?usage: $0 <function-name> [payload-file]}"
PAYLOAD="${2:-event.json}"
RESPONSE_FILE=$(mktemp)
trap 'rm -f "$RESPONSE_FILE"' EXIT
echo "→ Invoking $FUNCTION with payload from $PAYLOAD..."
RESULT=$(aws lambda invoke \
--function-name "$FUNCTION" \
--payload "file://$PAYLOAD" \
--cli-binary-format raw-in-base64-out \
--log-type Tail \
"$RESPONSE_FILE")
# Surface logs
echo "→ Logs:"
echo "$RESULT" | jq -r '.LogResult' | base64 --decode
# Check for function errors
FUNCTION_ERROR=$(echo "$RESULT" | jq -r '.FunctionError // empty')
if [ -n "$FUNCTION_ERROR" ]; then
echo "✗ Function error: $FUNCTION_ERROR"
echo "→ Response:"
cat "$RESPONSE_FILE" | jq
exit 1
fi
echo "→ Response:"
cat "$RESPONSE_FILE" | jq$ ./invoke.sh order-processor event.json
→ Invoking order-processor with payload from event.json...
→ Logs:
START RequestId: abc123 Version: $LATEST
Processing order 12345
END RequestId: abc123
REPORT Duration: 234.56 ms ...
→ Response:
{ "orderId": "12345", "status": "processed" }Caveats
--cli-binary-format raw-in-base64-outis mandatory in CLI v2. Without it, the payload gets double-encoded and Lambda receives garbage. Setcli_binary_format = raw-in-base64-outin~/.aws/configto make it default per profile.- The response file argument is positional and required. It comes after all flags. If you forget it, you get a confusing error about missing parameters.
FunctionErroris the canary for unhandled exceptions. A successful invoke withFunctionError: Unhandledmeans your function threw and you need to read the response payload for the actual error.--log-type Tailonly returns the last 4KB of logs. For longer logs, useaws logs tailagainst the function's log group.- Async invokes don't return logs.
--invocation-type Eventis fire-and-forget. To debug async invokes, use CloudWatch Logs. - Don't use this in production for high-volume invocation. It's a CLI tool, not a low-latency runtime client. Use the SDK in code.
Related Snippets & Reading
- Tail CloudWatch Logs Live — for the full log stream beyond 4KB
- Debug Which AWS Identity You're Using — when invoke fails with access denied
- aws lambda invoke reference — official docs
Frequently Asked Questions
What's the difference between RequestResponse and Event invocation?
RequestResponse (the default) is synchronous — the CLI waits for the function to finish and returns the response. Event is fire-and-forget — the CLI returns immediately with a 202 status, and the function runs in the background. Use RequestResponse for testing, Event for triggering background work.
Why does aws lambda invoke return success even when my function throws?
Function-level errors are returned in the response payload, not the CLI exit code. The CLI only fails if the invocation itself fails (auth error, function not found). Always check the response JSON for an errorMessage field, or use --query 'FunctionError' to surface it.