Skip to main content

Outputs

Action output in Triggers v2 has two separate jobs:

  • the result payload can keep moving through the graph
  • the runtime emits CompletionEvent so the system can observe what happened

Those are related, but they are not the same data path.

Result payload versus observability event

This is the most important distinction to keep straight:

  • action results are for downstream routing and binding
  • CompletionEvent is for observability

The wire contract does not put the action result body inside CompletionEvent. If you assume it does, run inspection and chaining behavior will seem inconsistent when the real issue is just a wrong mental model.

Why result_event matters

result_event is the catalog metadata that tells Studio and downstream consumers how an action result is shaped. It becomes important as soon as you stop doing single-action smoke tests and start wiring one step from another. In the current Go and Python SDKs it is auto-derived for flat typed object outputs with derivable fields; empty outputs omit it unless you override it explicitly.

In the flow_lab example:

  • parse returns {message, length}
  • wrap consumes message and optional prefix

That chain is manageable in Studio because the upstream action exposes a result shape that downstream bindings can understand, and the downstream action can combine those bound fields with literal overrides.

Chaining shape

The recommended chaining pattern is:

source
-> service(flow_lab)
-> action(parse)
-> service(flow_lab)
-> action(wrap)

The extra service segment is not about output formatting. It is part of the graph grammar. Action results do not jump directly from one action node to another without the downstream service boundary being represented in the graph.

Output topics

Once an action result is in the graph, one common next step is an output-topic node. That is the point where you stop treating the action result as internal flow state and start treating it as something to emit to another system boundary.

That is why the broader graph grammar includes nodes beyond service and action. A useful local flow can end at wrap, but production-shaped flows often continue beyond it.

Failure path

Successful output routing and failure handling are also separate concerns:

  • success publishes the next step and emits a success CompletionEvent
  • permanent failures or exhausted retries publish to DLQ and emit failure observability

The DLQ record preserves the original envelope and body for inspection. It is not a substitute for the success-path result payload.