I currently have 2 Lambda functions in a Step Function. One always returns an array of numbers:
export const handler = async(event) => {
const response = {
statusCode: 200,
body: [1, 2, 3]
};
return response;
};
The number elements are passed to a Map
state, where an iterator function adds 1 to the input:
export const handler = async(event) => {
const response = {
statusCode: 200,
body: event + 1,
};
return response;
};
I have set up a Step Function to run the 1st function and then run the 2nd function on each element of the output array:
{
"StartAt": "return array",
"States": {
"return array": {
"Type": "Task",
"Resource": "arn:aws:states:::lambda:invoke",
"OutputPath": "$.Payload",
"Parameters": {
"Payload.$": "$",
"FunctionName": "...return-array:$LATEST"
},
"Retry": [
...
],
"Next": "Map"
},
"Map": {
"Type": "Map",
"ItemProcessor": {
"ProcessorConfig": {
"Mode": "INLINE"
},
"StartAt": "add",
"States": {
"add": {
"Type": "Task",
"Resource": "arn:aws:states:::lambda:invoke",
"OutputPath": "$.Payload",
"Parameters": {
"Payload.$": "$",
"FunctionName": "...add:$LATEST"
},
"Retry": [
...
],
"End": true
}
}
},
"End": true,
"ItemsPath": "$.body"
}
}
}
However, I'm getting an error:
An error occurred while executing the state 'add' (entered at the event id #12). The Parameters '{"FunctionName":"...add:$LATEST","Payload":1}' could not be used to start the Task: [The value for the field 'Payload' must be a STRING]
It looks like the fix should be easy enough but I can't seem to figure out how to convert each element of [1, 2, 3]
to a string before passing it to the next step.
As you discovered, your Map state passes number
scalars to each iteration, but the Payload
expects key-values or a string.
Convert the number payload (at path $
) to a string with the JsonToString
intrinsic function in the add
Lambda task's parameters:
"add": {
"Parameters": {
"Payload.$": "States.JsonToString($)",
"FunctionName": "...add:$LATEST"
}
...
}
Your Lambda now receives a stringified number as its event
. Modify your add
handler code accordingly: body: parseInt(event,10) + 1
to convert the event
back to a number.
Alternatively, you could replace your add
Lambda task with a Pass
state as the Map's iterator. The trick is another intrinsic function, MathAdd
. MathAdd
accepts two numbers, so there's no type conversion hassle:
"Add": {
"Type": "Pass",
"Parameters": {
"add.$": "States.MathAdd($, 1)"
},
"OutputPath": "$.add",
"Next": "AnotherTask"
},