pipeline array. Each execution of the pipeline runs every stage in order — Devset builds the outbound message payload, optionally dispatches it to the broker, and updates workflow state before moving to the next stage. You can configure a stage to repeat, pause, pull data from MongoDB, or emit conditionally based on live values.
Full Stage Example
The following stage generates a random order payload, emits it to the broker only when the running count is below one hundred, and updates two state values:Stage Fields
A unique identifier for this stage within the workflow. Used in logs and error messages to pinpoint which step produced an issue. Stage identifiers do not need to be globally unique across workflows — only within the same
pipeline array.A logical event or schema name associated with this stage. Devset uses this for display purposes and schema lookup when no explicit
schemaId is provided on the stage.Overrides the workflow-level
schemaId for this stage only. Use this when a pipeline publishes messages to multiple schemas or schema versions within the same workflow run.Controls how the initial payload for this stage is seeded.
"none"— start with an empty payload object. All fields must be assigned viaset."previous-stage"— copy the fully resolved payload from the previous stage as the starting point. Useful when you want to evolve a message across multiple stages without repeating common fields.
Controls whether the resolved payload is dispatched to the broker.
true— always emit.false— build the payload and update state but do not send. This is also the behaviour whenemitis omitted entirely.- A
{ "$fn": "..." }expression — evaluate the function and emit only if the result is truthy.
A duration string to pause before the message is dispatched. Supported units:
ms (milliseconds), s (seconds), m (minutes). For example "1s" waits one second, "500ms" waits 500 milliseconds, and "2m" waits two minutes. Useful for simulating realistic timing between events in a scenario.The
wait pause is skipped entirely when running in the Devset Playground or any simulation mode. It only takes effect during a live execution against a real broker.A map of payload field names to their assigned values. Each value can be a literal string or number, or a
{ "$fn": "..." } expression. Fields are resolved in declaration order, so you can reference an earlier field’s value in a later assignment within the same set block.A map of workflow state paths to new values. Mutations are applied after the payload is fully resolved. Paths use dot notation to target nested state keys — for example
"order.total" updates state.order.total. See the Workflow DSL page for details on how state persists across executions.Key-value pairs to include as message headers. For Kafka, these become record headers. For RabbitMQ, they are added to the message’s
headers property. Values must be plain strings.The Kafka message key. Accepts a literal string or a
{ "$fn": "..." } expression. Kafka uses this key for partition assignment, so consistent keys route related messages to the same partition.Repeat this stage the specified number of times before moving to the next stage. The stage’s
set and state blocks are re-evaluated on every iteration, so each repeat produces a fresh payload. Combine with repeatWhile or repeatUntil for conditional loops.A
{ "$fn": "..." } expression evaluated before each repeat iteration. If the expression returns false, the loop stops and the pipeline advances to the next stage. The condition is checked before the first iteration, so the stage may execute zero times if the condition is immediately false.A
{ "$fn": "..." } expression evaluated after each repeat iteration. If the expression returns true, the loop stops. Because the check happens after execution, the stage always runs at least once regardless of the initial condition.A MongoDB lookup block that runs before the stage’s
set block is evaluated. The results are loaded into workflow state so you can use them in subsequent field assignments. See Query Block below.Configures the binary framing applied to the serialized Protobuf payload. Only relevant when the workflow’s
contentType is "application/x-protobuf". See the Wire Format reference for full details.Repeat Loops
Therepeat, repeatWhile, and repeatUntil fields give you full control over how many times a single stage executes before the pipeline advances.
Fixed repeat
Userepeat alone to run a stage an exact number of times:
Pre-condition loop with repeatWhile
repeatWhile is checked before each iteration. The stage stops as soon as the condition becomes false:
Post-condition loop with repeatUntil
repeatUntil is checked after each iteration. The stage always executes at least once:
Conditional Emit
Theemit field accepts a { "$fn": "..." } expression that is evaluated at runtime. This lets you send messages only when certain conditions hold, without splitting logic across multiple stages.
emit expressions.
Query Block
Thequery block performs a MongoDB lookup before the stage’s payload is assembled. Use it to seed workflow state with real data from your database, then reference those values in set assignments.
The name of a configured database connector. This must match a connector registered in your Devset environment.
The MongoDB database name to query.
The MongoDB collection name to query.
A MongoDB filter document using standard
db.collection.find({...}) syntax. For example, { "status": "ACTIVE" } returns only active documents.Maps document fields to workflow state paths. The key is the target state path (dot notation) and the value is the source field name from the matched document.After the query runs,
state.lookup.userId holds the document’s userId value and state.lookup.planTier holds subscription.tier.Full Query Example
The
query block runs once per stage execution. If the filter matches multiple documents, Devset uses the first result. Design your find filter to be as specific as possible to avoid non-deterministic lookups.