Skip to main content
Skip table of contents

Merge Tasks

LAST UPDATED: JUNE 20, 2025

Merge tasks collect desired playbook data and combine them into a single array. This array—the merge result—is found in the Raw Data tab of the Playbook Task Details popover.

5c7d0e4d-dd46-42d3-8be9-e54d1e25820c.png

Merge is useful when consolidating data from upstream task nodes that arrive either as:

  • Distinct parallel playbook nodes

Example - Merging Parallel Nodes *

OBJECTIVE – Merge the return data of three parallel task nodes into a string array.


  1. Build the following playbook:

  2. Configure task A to return the string "A", task B to return "B", and task C to return "C".

    Frame 20 (4)-20250603-020456.png
  3. Provide the following configuration as input for the Merge task:

    JSON
    {
      "groupBy": "Playbook Instance",
      "dataJsonPath": "$.*.returnData"
    }
    image-20250603-015154.png
  4. Test run the playbook.

    Frame 1 (31)-20250602-235821.png

  5. Observe the execution results for each task.

    • Data Formatter tasks:

      Frame 16 (5)-20250603-012513.png
    • Merge task:

      Frame 17 (7)-20250603-013016.png
  • Multiple instances of the same task

Example - Merging Data from Instances of the Same Task *

OBJECTIVE – Use an Unwind task to split a list of objects into individual objects, update each one using a Data Formatter task, and then recombine the modified objects with a Merge task.


  1. Build the following playbook:

  2. Provide the following JSON data as input for the JSON Data parameter of the Unwind task:

    JSON
    [
      { "key1": "value1", "key2": "value2" },
      { "key3": "value3", "key4": "value4" },
      { "key5": "value5", "key6": "value6" }
    ]
  3. Provide the following Jinja logic as input for the Process Object (Data Formatter) task:

    JSON
    {
      {% set k1 = PlaybookData | jsonpath('$.Unwind.contextData.data.key1') %}
      {% set k2 = PlaybookData | jsonpath('$.Unwind.contextData.data.key2') %}
      {% set k3 = PlaybookData | jsonpath('$.Unwind.contextData.data.key3') %}
      {% set k4 = PlaybookData | jsonpath('$.Unwind.contextData.data.key4') %}
      {% set k5 = PlaybookData | jsonpath('$.Unwind.contextData.data.key5') %}
      {% set k6 = PlaybookData | jsonpath('$.Unwind.contextData.data.key6') %}
    
      {% if k1 %}
      "key1": "UPDATED VALUE 1"{% if k2 %},{% endif %}
      {% endif %}
      {% if k2 %}
      "key2": "UPDATED VALUE 2"{% if k3 %},{% endif %}
      {% endif %}
      {% if k3 %}
      "key3": "UPDATED VALUE 3"{% if k4 %},{% endif %}
      {% endif %}
      {% if k4 %}
      "key4": "UPDATED VALUE 4"{% if k5 %},{% endif %}
      {% endif %}
      {% if k5 %}
      "key5": "UPDATED VALUE 5"{% if k6 %},{% endif %}
      {% endif %}
      {% if k6 %}
      "key6": "UPDATED VALUE 6"
      {% endif %}
    }
  4. Provide the following configuration as input for the Merge task:

    JSON
    {
      "groupBy": "Task",
      "taskName": "Unwind",
      "dataJsonPath": "$['Process Object'].returnData"
    }
  5. Test run the playbook.

    Frame 1 (31)-20250602-235821.png

  6. Observe the execution results for each task.

    • Unwind task:

      Frame 49-20250609-195434.png
    • Process Object (Data Formatter) task:

      Frame 50-20250609-195755.png
    • Merge task:

      Frame 51-20250609-195922.png

Merge Condition

The merge condition is a JSON object that tells the system how to group data based on a shared lineage—such as by Playbook Instance, Task, Task Instance, or Path—(lineage grouping), which data to filter, and the required match count for producing the merge result.

Frame 48 (6)-20250609-190302.png

Merge Condition Schema

JSON
{
  "groupBy": "<Playbook Instance | Task | Task Instance | Path>",
  "taskName": "<Display name of the task>",
  "paths": [
    "<JSON path 1>",
    "<JSON path 2>",
    "<JSON path 3>",
    ...
    "<JSON path N>"
  ],
  "dataJsonPath": "<JSON path>",
  "count": <Number>
}

The following tables list the (case-sensitive) keys for the merge condition.

Grouping Fields

These key-value pairs define the criteria for grouping data that share a common lineage. This defines the lineage grouping behavior.

Key

Data Type

Description

groupBy

string

taskName

string

  • The task display name used to select execution paths to merge.

  • The taskName key is used in conjunction with the groupBy: "Task" and groupBy: "Task Instance" configurations.

paths

array<string>

  • The array of node-anchored JSON path expressions that the Merge task evaluates within task outputs.

    • Any execution lineage containing at least one listed path is included in the merge result.

  • The paths key is used in conjunction with the groupBy: "Path" configuration.

Post-Grouping Fields

These key-value pairs control how grouped data is handled after lineage grouping has been applied.

Key

Data Type

Description

dataJsonPath

string

  • The JSON path expression that returns the data of one task node per matched lineage.

    • Original merge array elements (full lineage objects) become the value at the specified path.

  • See the example below.

count

integer

  • The number of matched execution-lineage objects required to trigger the merge and generate the array for downstream workflows.

  • By default, all matched execution-lineage objects are returned in the merge output.

  • See the example below.

Example - Using the dataJsonPath Key

OBJECTIVE – Understand the functionality and benefit of using the dataJsonPath key.


  1. Build the following playbook:

  2. Configure the playbook tasks:

    • Configure task A to return the string "A".

    • Configure task B to return the string "B".

    • Configure task C to return the array:

      JSON
      [
        { "key1": "value1", "key2": "value2" },
        { "key3": "value3", "key4": "value4" },
        { "key5": "value5", "key6": "value6" }
      ]
    • Configure Unwind to target {{ $.PlaybookData.C.returnData }} (i.e., the JSON Data parameter).

    • Configure task ABC to return "Hypothetically processed data".

    • Configure Merge with the following condition:

      JSON
      {
        "groupBy": "Playbook Instance"
      }
  3. Test run the playbook.

    Frame 1 (31)-20250602-235821.png

  4. Open the D’s task details, then select the Playbook Data tab.

    Frame 54-20250610-003938.png
  5. Expand the Merge > rawData field, then inspect each object in the rawData array.

    Frame 53-20250610-000718.png

    Each object represents an execution lineage that led to the Merge task. In a real vSOC operation, this array may be significant in length.

  6. Update the merge condition to the following:

    JSON
    {
      "groupBy": "Playbook Instance",
      "dataJsonPath": "$['ABC'].returnData"
    }
  7. Repeat steps 3–5, then recheck the rawData field.

    Frame 56-20250610-012012.png

    This time, the rawData array contains only the returnData from task ABC instances.

READER NOTE

  • In a real scenario, each entry in the rawData array would typically contain distinct data, rather than identical hardcoded values.

  • The reduction to targeted task results simplifies data handling, improves clarity, and better supports debugging and modification.

Example - Using the count Key

OBJECTIVE – Understand the functionality and benefit of using the count key.


  1. Build the following playbook:

    b31e2f85-1586-4a4b-a572-6808a2e04e37.png
  1. Configure the playbook tasks:

    • Configure task A to return the string "A".

    • Configure task B to return the string "B".

    • Configure task C to return the array:

      JSON
      [
        { "key1": "value1", "key2": "value2" },
        { "key3": "value3", "key4": "value4" },
        { "key5": "value5", "key6": "value6" }
      ]
    • Configure Unwind to target {{ $.PlaybookData.C.returnData }}.

    • Configure task ABC to return "Hypothetically processed data".

    • Configure Merge with the following condition:

      JSON
      {
        "groupBy": "Playbook Instance"
      }
  2. Test run the playbook.

    Frame 1 (31)-20250602-235821.png

  3. Open the D’s task details, then select the Playbook Data tab.

    Frame 54-20250610-003938.png
  4. Expand the Merge > rawData field, then count the number of objects in the rawData array.

    Frame 53-20250610-000718.png

    Each object represents an execution lineage that led to the Merge task. There is a count of five objects.

  5. Update the merge condition to the following:

    JSON
    {
      "groupBy": "Playbook Instance",
      "count": 2
    }
  6. Repeat steps 3–5, then recheck the rawData field.

    Frame 57-20250610-025457.png

    This time, there is a count of two objects in the rawData array.

TAKEAWAY

The count key limits the number of execution-lineage objects returned in the rawData field.


FAQ

What are execution-lineage objects?

Execution-lineage object = A JSON object containing the full sequence of task metadata and outputs that lead to an active execution point.

EXAMPLE

Given the following playbook build configuration:

Provided that the Merge task serves as the reference active execution point, the following are the execution lineages and their corresponding object representations:

LINEAGE 1

Frame 116 (1)-20250620-174137.png
JSON
{
  "DataSource": { ... },
  "A1": { ... }
}

LINEAGE 2

Frame 115-20250620-171658.png
JSON
{
  "DataSource": { ... },
  "B1": { ... },
  "B2.1": { ... }
}

LINEAGE 3

Frame 114 (2)-20250620-180019.png
JSON
{
  "DataSource": { ... },
  "B1": { ... },
  "B2.2": { ... }
}

Assuming the default merge condition is applied, the resulting merged output will be as follows:

JSON
[
  {
    "DataSource": { ... },
    "A1": { ... }
  },
  {
    "DataSource": { ... },
    "B1": { ... },
    "B2.1": { ... }
  },
  {
    "DataSource": { ... },
    "B1": { ... },
    "B2.2": { ... }
  }
]

TAKEAWAYS

  • An execution-lineage object describes a complete ancestral chain of task executions.

  • The default merge condition—unlike other grouping modes—will not, on its own, cause the merge result to exclude execution-lineage objects of any:

    • Divergent lineages (e.g., as with lineage 1 and lineage 2/3)

    • Sibling lineages (e.g., as with lineage 2 and lineage 3)

How can one use the dataJsonPath key to extract deeply nested values?

EXAMPLE 1

  1. Build the following playbook.

  2. Configure task A1 to return the following output:

    JSON
    [
      { "key1": "value1", "key2": "value2" },
      { "key3": "value3", "key4": "value4" },
      { "key5": "value5", "key6": "value6" }
    ]
  3. Configure Merge with the following condition:

    JSON
    {
      "groupBy": "Path",
      "paths": ["$.['A1'].returnData"],
      "dataJsonPath": "$['A1'].returnData[?(@.key2=='value2')]"
    }
  4. Test run the playbook.

    Frame 1 (31)-20250602-235821.png

  5. Check the merge results.
    MERGE RESULT

    JSON
    [
      {
        "key1": "value1",
        "key2": "value2"
      }
    ]
    Frame 59-20250610-212953.png

EXAMPLE 2

  1. Configure task A1 to return the following output:

    JSON
    [
      {
        "A": {
          "B": {
            "C": {
              "D": {
                "TARGET": {
                  "id": 1,
                  "value": "match"
                }
              }
            }
          }
        }
      },
      {
        "A": {
          "B": {
            "C": {
              "D": {
                "TARGET": {
                  "id": 2,
                  "value": "no-match"
                }
              }
            }
          }
        }
      }
    ]
  2. Configure Merge with the following condition:

    JSON
    {
      "groupBy": "Path",
      "paths": ["$['A1'].returnData"],
      "dataJsonPath": "$['A1'].returnData[?(@.A.B.C.D.TARGET.value=='match')].A.B.C.D.TARGET"
    }
  3. Test run the playbook.

    Frame 1 (31)-20250602-235821.png

  4. Check the merge result.
    MERGE RESULT

    JSON
    [
      {
        "id": 1,
        "value": "match"
      }
    ]
    Frame 58 (2)-20250610-212624.png
JavaScript errors detected

Please note, these errors can depend on your browser setup.

If this problem persists, please contact our support.