Group By ExecModule
Overview
GroupByModule version 2.0.0 groups an ordered array of workflow objects by one or more nested scalar fields. It calculates bounded local aggregates without network access, credentials, or external side effects.
Version 2 replaces malformed catalog outputs, incomplete configuration metadata, delimiter-serialized keys, nondeterministic group ordering, silently skipped records, and count fallbacks for unknown aggregation names. Group keys retain their JSON-compatible Java types, and the first input record for each distinct key establishes output order.
Usage
- Put an array of objects in workflow state.
- Set
source_pathto that array. - Set
group_byto one path string or an ordered array of up to eight paths. - Configure up to 16 aggregation objects using
operation,field, andas. - Choose bounded
max_input_itemsandmax_groupsvalues for the downstream workload. - Read the canonical result from
groups. The configuredoutput_fieldis a compatibility alias.
Inputs
| Name | Type | Required | Limit | Description |
|---|---|---|---|---|
records | array of objects | Yes | 100,000 hard maximum | Value resolved from source_path. Every item must be an object. |
Nested object segments and bounded zero-based array indexes are supported in paths, such as payload.batches[0].sales or customer.region. Grouping fields must resolve to strings, numbers, booleans, or null; arrays and objects are rejected as group keys.
Outputs
| Name | Type | Condition | Description |
|---|---|---|---|
status | string | Always | success or error. |
groups | array | Success | Canonical ordered group results. |
grouped_items | array | Default alias | Compatibility alias selected by the default output_field. |
groupCount | integer | Success | Number of distinct groups. |
group_count | integer | Success | Legacy alias for groupCount. |
inputCount | integer | Success | Number of validated source records. |
errorCode | string | Error | Stable machine-readable failure code. |
error | string | Error | Safe actionable failure message. |
Each group result contains its grouping fields using the original scalar values, followed by configured aggregation aliases. When include_items is true, it also contains the validated source records in items.
IntegrationAccount Requirements
None. GroupByModule is a local deterministic transformation and must not receive credentials. Inputs and outputs are classified as confidential because grouping can expose sensitive segments or aggregate business data; downstream workflows must preserve normal ACL and data-handling controls.
Configuration
| Field | Type | Required | Default | Description |
|---|---|---|---|---|
source_path | text | Yes | — | Nested path to the source array. |
group_by | string or JSON array | Yes | — | One through eight unique nested scalar field paths. |
aggregations | JSON array | No | one count aggregate | Up to 16 aggregation objects. |
include_items | boolean | No | false | Include source records in each group result. |
output_field | text | No | grouped_items | Compatibility alias for canonical groups. |
max_input_items | integer | No | 10000 | Per-execution input bound; hard maximum 100,000. |
max_groups | integer | No | 1000 | Per-execution distinct-group bound; hard maximum 10,000. |
Paths are at most 256 characters. Output aliases are at most 128 characters, must be safe identifiers, and cannot replace canonical output fields or grouping fields.
Operations
Every aggregation object accepts an operation, an output alias in as, and—except for count—a nested field path.
| Operation | Result |
|---|---|
count | Number of records in the group. |
sum | Sum of present finite numeric values. |
avg | Mean of present finite numeric values, or null when none are present. |
stddev | Population standard deviation, 0.0 for one value, or null for none. |
min / max | Numeric extreme when all values are numeric; lexical extreme when all are strings. |
first / last | First or last field value in source order. |
concat | Present values joined with , , bounded to 1,000,000 characters. |
collect | Present values retained in source order. |
Numeric aggregations accept finite JSON numbers and finite numeric strings. A present nonnumeric or non-finite value fails the full execution instead of silently contributing zero. min and max reject mixed incomparable types.
Errors and Failure Modes
| Error code | Cause | Recovery |
|---|---|---|
VALIDATION_ERROR | A path, boolean, integer, alias, duplicate grouping path, or aggregation shape is invalid. | Correct the named configuration. |
INVALID_SOURCE | source_path does not resolve to an array. | Populate an array or correct the path. |
INVALID_RECORD | A source item is not an object or has a non-string field name. | Normalize every source record before grouping. |
INVALID_GROUP_KEY | A grouping field resolves to an array or object. | Select or derive a scalar key. |
INVALID_AGGREGATION | An operation is unsupported. | Choose one of the documented operations. |
INVALID_NUMERIC_VALUE | A numeric aggregation receives a present nonnumeric or non-finite value. | Clean or filter the field before grouping. |
INCOMPARABLE_VALUES | min or max receives mixed incompatible types. | Normalize the field to all numbers or all strings. |
INPUT_LIMIT_EXCEEDED | Source records exceed max_input_items. | Filter, partition, or deliberately raise the bound. |
GROUP_LIMIT_EXCEEDED | Distinct keys exceed max_groups. | Partition the input or deliberately raise the bound. |
RESULT_LIMIT_EXCEEDED | A concatenated result exceeds its character limit. | Use collect, truncate upstream, or partition the data. |
EXECUTION_ERROR | An unexpected local failure occurred. | Preserve inputs, inspect sanitized diagnostics, and fix the defect before retrying. |
Failures clear partial results. Event logs include only group counts or stable error codes—not input records, keys, or aggregate values.
Example
Configuration:
{
"source_path": "payload.sales",
"group_by": ["region"],
"aggregations": [
{"field": "amount", "operation": "sum", "as": "revenue"},
{"field": "amount", "operation": "avg", "as": "averageOrder"},
{"operation": "count", "as": "orders"}
],
"include_items": false,
"max_input_items": 1000,
"max_groups": 50
}
Input:
{
"payload": {
"sales": [
{"region": "west", "amount": 12.5},
{"region": "east", "amount": 4.0},
{"region": "west", "amount": 7.5}
]
}
}
Expected result:
{
"status": "success",
"groups": [
{"region": "west", "revenue": 20.0, "averageOrder": 10.0, "orders": 2},
{"region": "east", "revenue": 4.0, "averageOrder": 4.0, "orders": 1}
],
"grouped_items": [
{"region": "west", "revenue": 20.0, "averageOrder": 10.0, "orders": 2},
{"region": "east", "revenue": 4.0, "averageOrder": 4.0, "orders": 1}
],
"groupCount": 2,
"group_count": 2,
"inputCount": 3
}
Notes
- Pagination: none. Inputs are already-materialized workflow values; partition large data upstream.
- Limits: eight grouping fields, 16 aggregations, 100,000 hard maximum input records, 10,000 hard maximum groups, and 1,000,000 concatenated characters.
- Ordering: groups follow first appearance in the source array; collected and included items retain source order.
- Key identity: numeric
7, string"7", booleantrue, andnullare distinct grouping values. Delimiter characters inside strings are not special. - Idempotency: natural and deterministic for the same ordered inputs and configuration.
- Rate limits: none; no provider or database is called.
- API constraints: none beyond normal workflow-state deserialization and the documented scalar-key rules.
- Destructive behavior: none. The module does not mutate source records or write outside workflow memory.
- Testing boundary: focused tests cover typed composite keys, ordering, every aggregation, defaults, aliases, malformed records, invalid numerics, bounds, and metadata serialization.
- Runtime boundary: merged source and published documentation do not update the deployed Workflow Studio catalog until a normal ValkyrAI backend release exposes version 2 through
/v1/modules/metadata.
See the ExecModule catalog, the neighboring Join module, and the Merge module.