How to retrieve variable in second task from first task using bash script?

Hi there, I am new to stackstorm. I need help to resolve the problem, I am having.

I am working on one workflow that will get variable information from first task and use that variable in second task using bash script. I see that is possible using python, but I would prefer to do with bash. Here is the workflow.

input:
  - value1
  - value2
  - value3

output:
  - value2: <% ctx().value2 %>
  - value3: <% ctx().value3 %>

tasks:
  task1:
    action: jobname.get_info value1=<% ctx(value1) %>
    next:
      - when: <% succeeded() %>
        publish:
          - stdout: <% result().stdout %>
          - stderr: <% result().stderr %>
          - value2: <% ctx("value2") %>, <% result().result %>
          - value3: <% ctx("value3") %>, <% result().result %>
      - do: task2
      - when: <% failed() %>
        publish: stderr=<% result().stderr %>
        do: fail

  task2:
    action: job.name2 value2=<% ctx(value2) %>
    next:
      - when: <% succeeded() %>
        publish:
          - stdout: <% result().stdout %>
          - stderr: <% result().stderr %>
      - do: task3
      - when: <% failed() %>
        publish: stderr=<% result().stderr %>
        do: fail

I see that the first job gets succeeded without any error, but the second job uses value2 in the execution, so it won’t move forward in execution and errors out.

{
  "output": null,
  "errors": [
    {
      "message": "YaqlEvaluationException: Unable to resolve key 'result' in expression '<% result().result %>' from context.",
      "task_transition_id": "noop__t0",
      "type": "error",
      "route": 0,
      "task_id": "task1"
    },
    {
      "message": "YaqlEvaluationException: Unable to evaluate expression '<% ctx(stdout) %>'. VariableUndefinedError: The variable \"stdout\" is undefined.",
      "type": "error"
    }
  ]
}

Thanks in advance!! :slight_smile:

You have a bug in your YAML. The task1.next block looks like this (represented in JSON) to make it more apparent:

[
  {
    "when": ...,
    "publish": ...
  },
  {
    "do": ...
  },
  {
    "when": ...,
    "publish": ...,
    "do": ...
  }
]

The dictionary for the do item does not have a when key, and the when item does not have a do key.

That is actually valid Orquesta, but it’s likely not what you want.

What that does is publish some values to the workflow context (when task1 is successful). If task1 fails, it transitions to the builtin fail task. And because the do block doesn’t have a when key, Orquesta will always try to transition to task2 regardless of whether task1 succeeds or fails - that’s not what you want.

I think you want the workflow to publish stdout, stderr, value2, and value3 to the workflow context and to transition to task2 only when task1 succeeds.

So to do that, you want to do the following (represented in JSON):

[
  {
    "when": ...,
    "publish": ...,
    "do": ...
  },
  {
    "when": ...,
    "publish": ...,
    "do": ...
  }
]

Or to represent that in YAML:

      - when: <% succeeded() %>
        publish:
          - stdout: <% result().stdout %>
          - stderr: <% result().stderr %>
          - value2: <% ctx("value2") %>, <% result().result %>
          - value3: <% ctx("value3") %>, <% result().result %>
        do: task2
      # ^ no longer a list item on its own, it's now in the
      #   same list item as the `when` and `publish` keys
      - when: <% failed() %>
        publish: stderr=<% result().stderr %>
        do: fail

@blag Thanks for putting time and effort to help me on the issue/problem I am having.

But here, I am looking solution of how do I publish value2 and value3 in task1 and use those values further on in workflow in other tasks where mentioned.

You can see I have used value2 in task2 and I am also going to use value2 and value3 in task 3 to accomplish the whole task.

Again thanks!!

Yep, I think I understand what you are trying to do, and my answer doesn’t change - you have an error in your workflow. It’s valid YAML but they way that it’s interpreted by Orquesta isn’t correct. If you change your workflow the way I suggested, then you should be able to access value2 and value3 in further tasks like task2 and task3.

@blag Thanks for your prompt reply on my comment. I have updated workflow and tried to execute by making changes in YAML as you suggested. The first task goes successful and then even it doesn’t initiate the second task and I get below error.

{
  "output": null,
  "errors": [
    {
      "message": "YaqlEvaluationException: Unable to resolve key 'result' in expression '<% result().result %>' from context.",
      "task_transition_id": "task2__t0",
      "type": "error",
      "route": 0,
      "task_id": "task1"
    },
    {
      "message": "YaqlEvaluationException: Unable to evaluate expression '<% ctx(stdout) %>'. VariableUndefinedError: The variable \"stdout\" is undefined.",
      "type": "error"
    }
  ]
}

FYI, here is the workflow:

input:
  - value1
  - value2
  - value3

output:
  - value2: <% ctx().value2 %>
  - value3: <% ctx().value3 %>

tasks:
  task1:
    action: jobname.get_info value1 =<% ctx(value1) %>
    next:
      - when: <% succeeded() %>
        publish:
          - stdout: <% result().stdout %>
          - stderr: <% result().stderr %>
          - value2: <% ctx("value2") %>, <% result().result %>
          - value3: <% ctx("value3") %>, <% result().result %>
        do: task2
      - when: <% failed() %>
        publish: stderr=<% result().stderr %>
        do: fail

  task2:
    action: jobname2 value2=<% ctx(value2) %>
    next:
      - when: <% succeeded() %>
        publish:
          - stdout: <% result().stdout %>
          - stderr: <% result().stderr %>
        do: task3
      - when: <% failed() %>
        publish: stderr=<% result().stderr %>
        do: fail

Hmmm, neither of those two errors make sense with the workflow you just posted. How are you updating your workflow on the ST2 server? Are you running st2 pack install ... and st2ctl reload every time you update the workflow? Or are you directly editing the workflow YAML file on the YAML server?

I run a job that kicks off st2 pack install on the server, once I update the workflow YAML file.

Hmmm, something appears to be amiss. If you’re on ST2 3.4+, I would load up your workflow in the workflow editor and make sure that the publish section of the task transitions shows what you expect, and double check that the “cached” workflow file in /opt/stackstorm/packs/<pack_name>/actions/workflows/<workflow_file_name>.yaml is what you expect.

I’m hoping that it’s not what you expect, because that would pinpoint the problem.

But if it is what you expect, then there’s something else going on that I’m not understanding.

@blag I really appreciate for taking time and replying to the issue I am having. I have verified, double checked the workflow file. Found that that is the change I am applying.

I also saw that when I execute the job, it takes the whole output considers value2 and executes the second job and fails since it doesn’t find value3.

I honestly not sure, what else to try on this issue.

Thanks again!!

Difficult to determine the exact fix without seeing the syntax of the action being called and how it outputs the results, but the error message posted above indicates that you are attempting assign a variable in Task1 to a key that cannot be resolved to in the output.

    {
      "message": "YaqlEvaluationException: Unable to resolve key 'result' in expression '<% result().result %>' from context.",
      "task_transition_id": "task2__t0",
      "type": "error",
      "route": 0,
      "task_id": "task1"
    },

In order for the publish to work and the variables to be published as listed in task1, the output of the “jobname.get_info” action would have to appear as follows (sample from the Orion Node Create action):

{
  "stdout": "",
  "stderr": "",
  "exit_code": 0,
  "result": {
    "label": "LABEL_DATA",
    "node_id": "9999999"
  }
}