State
State
Overview
Whenever the service receives an API call or an event occurs (e.g., an item is added to a queue or a timer event fires), a message is created. This message is passed through the configured connector pipeline with relevant data attached to the headers or payload of the message. This section describes how that message flows through the pipeline and the common inbuilt pipes used to manipulate it.
The ILokiMessage Interface
ILokiMessage is the interface representing the core message structure used throughout Variant applications. Each message, along with its associated transactional and synchronization metadata, is encapsulated in a LokiMessage class.

The key components of a LokiMessage are:
-
Headers: Key-value pairs used for routing, message enrichment, and metadata handling.
-
Payload: The primary data carried by the message. Messages may have multiple data parts, with
Payloadbeing the first. -
CreateSpawnedMessage() / IsSpawnedMessage: These handle message spawning, where new messages are derived from a parent message (e.g., in batch processing). This supports correlation and tracking of spawned messages.
The ModifyMessageStrategy
.NET Core Implementation
The central strategy for modifying a LokiMessage is the ModifyMessageStrategy class. Below is a visual of its structure:

This strategy includes several injected properties:
-
Namespace: Specifies the header name where the value is stored. If omitted, the value is stored as the payload. Defaults to
Response. -
Value: The content to be stored, which can be a string, object, or substitution expression.
-
TempValues: A transient data structure available only during the current strategy execution. Access using
${TempValues.property}. -
AppendValue: If
true, appends the value to an array. If the namespace is not an array, one is created. -
ForceDeepCopyOfJToken: Ensures the stored JToken is a deep copy to prevent unwanted mutation of shared data.
[!NOTE] The
Responseheader is commonly used by HTTP connectors to return values in API responses. These are typically serialized viaVariant.Json.ConvertObjectToJsonStrategyPipe.
YAML Implementations
Variant provides multiple specialisations of the ModifyMessageStrategyPipe, optimised for different use cases.
Default Implementation
- key: Variant.Core.ModifyMessageStrategyPipe
value:
pipe: Variant.Core.ModifyMessagePipe
replacements:
CAN_EXECUTE_EXPRESSION: null
CAN_EXECUTE_STRATEGY: null
CONTINUATION_POLICY: Default
VALUE:
TEMP_VALUES:
NAMESPACE: Response
APPEND_VALUE: False
FORCE_DEEP_COPY_OF_J_TOKEN: False
defaults:
LOG_ERRORS: True
ACTIVITY_NAME:
EXECUTION_FLOW_STRATEGY: null
MODIFY_MESSAGE_STRATEGY:
strategy: Variant.Core.ModifyMessageStrategy
Specialisations
Specialised versions of the strategy provide streamlined usage for common scenarios. These include:
-
General-purpose specialisations:
-
Variant.Core.Simple.ModifyMessageArrayStrategyPipe -
Variant.Core.Simple.ModifyMessageStrategyPipe
-
-
API helper specialisations:
-
Variant.Core.SetResponse -
Variant.Core.SetResponseHeaders -
Variant.Core.SetResponseStatusCodeAndHeaders
-
Example specialisations:
- key: Variant.Core.ModifyMessageArrayStrategyPipe
value:
pipe: Variant.Core.ModifyMessageStrategyPipe
replacements:
CAN_EXECUTE_EXPRESSION: null
CONTINUATION_POLICY: Default
VALUE: null
TEMP_VALUES: null
NAMESPACE: Response
defaults:
APPEND_VALUE: true
- key: Variant.Core.SetResponse
value:
pipe: Variant.Core.ModifyMessageStrategyPipe
replacements:
RESPONSE:
defaults:
NAMESPACE: Response
VALUE: RESPONSE
- key: Variant.Core.SetResponseHeaders
value:
pipe: Variant.Core.ModifyMessageStrategyPipe
replacements:
HEADERS:
defaults:
NAMESPACE!: Response.Headers
VALUE: HEADERS
- key: Variant.Core.SetResponseStatusCodeAndHeaders
value:
pipe: Variant.Core.DefaultScopedPipe
replacements:
HEADERS: null
STATUS_CODE: null
RESPONSE: null
defaults:
SCOPED_PIPES:
- pipe: Variant.Core.ModifyMessageStrategyPipe
NAMESPACE!: Response.Headers
VALUE!: HEADERS
- pipe: Variant.Core.ModifyMessageStrategyPipe
NAMESPACE!: Response.StatusCode
VALUE!: STATUS_CODE
- pipe: Variant.Core.ModifyMessageStrategyPipe
NAMESPACE!: Response
VALUE!: RESPONSE
[!NOTE]
SetResponseStatusCodeAndHeadersshould only be used for successful responses (status < 300). UseThrowErrorBreakPipefor error handling scenarios.