8

I'm doctoring up my first step function, and as a newb into this I am struggling to make this work right. The documentation on AWS is helpful but lacks examples of what I am trying understand. I found a couple similar issues on the site here, but they didn't really answer my question either.

I have a test Step Function that works really simply. I have a small Lambda function that kicks out a single line JSON with a "Count" from a request in a DynamoDB:

def lambda_handler(event, context):
    """lambda_handler

    Keyword arguments:
    event -- dict -- A dict of parameters to be validated.
    context -- 

    Return:
    json object with the hubID from DynamoDB of the new hub. 

    Exceptions:
    None
    """
    # Prep the Boto3 resources needed
    dynamodb        = boto3.resource('dynamodb')
    table           = dynamodb.Table('TransitHubs')

    # By default we assume there are no new hubs
    newhub = { 'Count' : 0 }

    # Query the DynamoDB to see if the name exists or not:
    response = table.query(
        IndexName='Status-index',
        KeyConditionExpression=Key('Status').eq("NEW"),
        Limit=1
    )

    if response['Count']:
        newhub['Count'] = response['Count']

    return json.dumps(newhub)

A normal output would be:

{ "Count": 1 }

And then I create this Step Function:

{
  "StartAt": "Task",
  "States": {
        "Task": {
      "Type": "Task",
      "Resource": "arn:aws:lambda:us-west-2:OMGSUPERSECRET:function:LaunchNode-get_new_hubs",
      "TimeoutSeconds": 60,
      "Next": "Choice"
    },
    "Choice": {
      "Type": "Choice",
      "Choices": [
        {
          "Variable": "$.Count",
          "NumericEquals": 0,
          "Next": "Failed"
        },
        {
          "Variable": "$.Count",
          "NumericEquals": 1,
          "Next": "Succeed"
        }
      ]
    },
    "Succeed": {
      "Type": "Succeed"
    },
    "Failed": {
      "Type": "Fail"
    }
  }
}

So I kick off the State Function and I get this output:

TaskStateExited

{
  "name": "Task",
  "output": {
    "Count": 1
  }
}

ChoiceStateEntered

{
  "name": "Choice",
  "input": {
    "Count": 1
  }
}

ExecutionFailed

{
  "error": "States.Runtime",
  "cause": "An error occurred while executing the state 'Choice' (entered at the event id #7). Invalid path '$.Count': The choice state's condition path references an invalid value."
}

So my question: I don't get why this is failing with that error message. Shouldn't Choice just pick up that value from the JSON? Isn't the default "$" input the "input" path?

2
  • In the step functions console on your failed execution, when you click the Task Lambda, and click the 'Output' tab, that will show the actual output of the Lambda. Does that show the structure you expect? Commented Apr 4, 2018 at 14:44
  • Thanks, that's partly what did lead me to figuring this out. I documented the answer to my issue below. Commented Apr 4, 2018 at 17:28

3 Answers 3

5

I have figured out what the issue is, and here it is:

In my Python code, I was attempting to json.dumps(newhub) for the response thinking that what I needed was a string output representing the json formatted response. But it appears that is incorrect. When I alter the code to be simply "return newhub" and return the DICT, the step-functions process accepts that correctly. I'm assuming it parses the DICT to JSON for me? But the output difference is clearly obvious:

old Task output from above returning json.dumps(newhub):

{
  "name": "Task",
  "output": {
    "Count": 1
  }
}

new Task output from above returning newhub:

{
  "Count": 1
}

And the Choice now correctly matches the Count variable in my output.

Sign up to request clarification or add additional context in comments.

Comments

3

In case this is helpful for someone else. I also experienced the kind of error you did ( you had the below... just copy-pasting yours... )

{
"error": "States.Runtime",
"cause": "An error occurred while executing the state 'Choice' (entered at the event id #7). Invalid path '$.Count': The choice state's condition path references an invalid value."
}

But my problem turned out when I was missing the "Count" key all together.

But I did not want verbose payloads.

But per reading these docs I discovered I can also do...

"Choice": {
"Type": "Choice",
"Choices": [
  {
    "And": [
      {
          "Variable": "$.Count",
          "IsPresent": true
          },
      {
          "Variable": "$.Count",
          "NumericEquals": 0,
          }
      ],
    "Next": "Failed"
    },
  {
    "And": [
      {
          "Variable": "$.Count",
          "IsPresent": true
          },
      {

          "Variable": "$.Count",
          "NumericEquals": 1,
          }
      ],
    "Next": "Succeed"
    }
  ]
},

Comments

0

even I was facing the same issue. Give the ResultPath as InputPath and give the choice value as .value name

{
  "Comment": "Step function to execute lengthy synchronous requests",
  "StartAt": "StartProcessing",
  "States": {
    "StartProcessing": {
      "Type": "Task",
      "Resource": "arn:aws:lambda:us-east-1:703569030910:function:shravanthDemo-shravanthGetItems-GHF7ZA1p6auQ",
      "InputPath": "$.lambda",
      "ResultPath": "$.lambda",
      "Next": "VerifyProcessor"
    },
    "VerifyProcessor": {
      "Type": "Choice",
      "Choices": [
        {
          "Variable": "$.lambda.cursor",
          "IsNull": false,
          "Next": "StartProcessing"
        },
        {
          "Variable": "$.lambda.cursor",
          "IsNull": true,
          "Next": "EndOfUpdate"
        }
      ]
    },
    "EndOfUpdate": {
      "Type": "Pass",
      "Result": "ProcessingComplete",
      "End": true
    }
  }
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.