# Process Instance A process instance is one execution of a [scheme](https://docs.workflowengine.io/get-started/concepts/scheme/). Workflow Engine creates a process instance for a specific scheme, assigns it a unique identifier, positions it at the initial [activity](https://docs.workflowengine.io/get-started/concepts/activity/), and persists its state to the database. Each process instance can carry its own parameters and business data through the workflow. ## What a process instance is Each process instance that Workflow Engine manages holds three pieces of state: the current activity name, the [parameter](https://docs.workflowengine.io/get-started/concepts/parameter/) values attached to this execution, and the transition history. Workflow Engine reads and writes this state through the persistence provider during execution. Transition history is recorded by default and can be disabled per activity. A process instance moves through several lifecycle states that Workflow Engine manages automatically: ```mermaid stateDiagram-v2 Initialized --> Running Running --> Idled Idled --> Running Running --> Finalized Running --> Terminated Running --> Error Error --> Running Finalized --> Running Terminated --> Running ``` Table: Process instance lifecycle states | State | What it means | |-------------|--------------------------------------------------------------------------------| | Initialized | Instance has just been created and positioned at the initial activity | | Running | Instance is being executed | | Idled | Instance is not executing and is waiting for external interaction | | Finalized | Instance has reached a final activity and is not executing | | Terminated | Instance was terminated after an error; commands and timers cannot continue it | | Error | Instance stopped after an error; commands and timers can continue it | A process instance reaches the **Finalized** state when it enters an activity marked as final (`IsFinal="true"`). Until then, the instance cycles between **Idled** (waiting) and **Running** (executing). By default, an unhandled execution error sets **Error** when a command or active timer exit remains; otherwise it sets **Terminated**. The **Finalized**, **Terminated**, and **Error** statuses can all return to **Running** through `SetStateAsync`, activity-setting methods, or `ResumeAsync`. The **Error** status also accepts commands and timers, while **Finalized** and **Terminated** do not. ## How a process instance works Workflow Engine creates a process instance when you call `CreateInstanceAsync` with a [scheme](https://docs.workflowengine.io/get-started/concepts/scheme/) code and a unique identifier: ```csharp var processId = Guid.NewGuid(); var createParams = new CreateInstanceParams("InvoiceApproval", processId) .AddPersistentParameter("Amount", 1500.00m) .AddPersistentParameter("OwnerId", "user-42"); await runtime.CreateInstanceAsync(createParams); ``` Once created, the process instance moves from one activity to the next when a [transition](https://docs.workflowengine.io/get-started/concepts/transition/) fires. A transition can be triggered by a [command](https://docs.workflowengine.io/get-started/concepts/command/), by a timer, or automatically when the process instance arrives at the activity. Workflow Engine finds the matching transition, evaluates any [conditions](https://docs.workflowengine.io/get-started/concepts/condition/) on it, and runs the configured [actions](https://docs.workflowengine.io/get-started/concepts/action/). If the trigger does not apply - for example a command is not available at the current activity, or the rule for that command does not permit the given identity - Workflow Engine does not fire the transition. ## Process instance properties A `ProcessInstance` object exposes properties that reveal the current state, the execution context, and the identity of the user who triggered the transition. These properties are accessible inside [actions](https://docs.workflowengine.io/get-started/concepts/action/), [conditions](https://docs.workflowengine.io/get-started/concepts/condition/), and [rules](https://docs.workflowengine.io/get-started/concepts/rule/) through the `processInstance` parameter. ### Identification properties These properties identify the process, its scheme, and its place in the process tree: Table: Process instance identification properties | Property | Type | Description | |-------------------|----------|-----------------------------------------------------------------------------------------------------------------| | `ProcessId` | `Guid` | Unique identifier of this process instance | | `SchemeId` | `Guid` | Identifier of the scheme version this instance runs on | | `SchemeCode` | `string` | The scheme code (name) that was used to create this instance | | `RootProcessId` | `Guid` | Root process identifier. Equals `ProcessId` for top-level processes; points to the root parent for subprocesses | | `ParentProcessId` | `Guid?` | Parent process identifier. `null` for top-level processes | | `TenantId` | `string` | Optional tenant identifier assigned when the process instance is created | `TenantId` is supplied through `CreateInstanceParams` when the process instance is created and is read-only afterward. In tenant-scoped contexts, Workflow Engine validates it before loading or changing the process instance. ### Current state properties These properties report where the process currently is and where it has been: Table: Process instance current state properties | Property | Type | Description | |----------------------------------|----------------------|--------------------------------------------------------------------| | `CurrentActivityName` | `string` | Name of the activity the process is currently at | | `CurrentActivity` | `ActivityDefinition` | The activity definition object the process is currently at | | `CurrentState` | `string` | Current business state name (from the activity's `State` property) | | `PreviousState` | `string` | Previous business state name recorded before the last transition | | `PreviousStateForDirect` | `string` | Previous state recorded during a Direct-classified transition | | `PreviousStateForReverse` | `string` | Previous state recorded during a Reverse-classified transition | | `PreviousActivityName` | `string` | Name of the previous activity | | `PreviousActivityForDirectName` | `string` | Name of the previous activity during a Direct transition | | `PreviousActivityForReverseName` | `string` | Name of the previous activity during a Reverse transition | ### Execution context properties These properties provide context about what is currently executing and why: Table: Process instance execution context properties | Property | Type | Description | |---------------------------------|------------------------|----------------------------------------------------------------------------------------| | `ExecutedActivity` | `ActivityDefinition` | The activity whose actions are currently being executed | | `ExecutedActivityState` | `string` | The state name of the currently executing activity | | `ExecutedTransition` | `TransitionDefinition` | The transition that is currently being executed | | `CurrentCommand` | `string` | Name of the command that triggered the current transition | | `ExecutedTimer` | `string` | Name of the timer that triggered the current transition | | `IsPreExecution` | `bool` | `true` if the action is running in Pre-Execution mode | | `IdentityIds` | `List` | Identities of users who could potentially execute a transition (Pre-Execution only) | | `IdentityIdsForCurrentActivity` | `List` | Identities who can execute a transition from the current activity (Pre-Execution only) | ### Identity properties These properties track who triggered the current execution: Table: Process instance identity properties | Property | Type | Description | |--------------------------|----------|-------------------------------------------------------------------------------------------| | `IdentityId` | `string` | Identifier of the user who executed the command or set the state | | `ImpersonatedIdentityId` | `string` | Identifier of the impersonated user, if using [Impersonation](https://docs.workflowengine.io/get-started/concepts/rule/) | ### Reading properties from code Inside an action, condition, or rule, access these properties directly from the `processInstance` parameter: ```csharp public async Task ExecuteActionAsync(string name, ProcessInstance processInstance, WorkflowRuntime runtime, string parameter, CancellationToken token) { // Identification var processId = processInstance.ProcessId; var schemeCode = processInstance.SchemeCode; var tenantId = processInstance.TenantId; // Current position var currentActivity = processInstance.CurrentActivityName; var currentState = processInstance.CurrentState; // Execution context var executingActivity = processInstance.ExecutedActivity?.Name; var executingTransition = processInstance.ExecutedTransition?.Name; var triggeredBy = processInstance.ExecutedTimer ?? processInstance.CurrentCommand; // Identity var userId = processInstance.IdentityId; Console.WriteLine( $"Process {processId} ({schemeCode}, tenant {tenantId}): at {currentActivity}," + $" state {currentState}, triggered by {triggeredBy}"); } ``` To read properties from application code outside actions, load the process instance through `WorkflowRuntime`: ```csharp var processInstance = await runtime.GetProcessInstanceAndFillProcessParametersAsync(processId); string activityName = processInstance.CurrentActivityName; string stateName = processInstance.CurrentState; ``` ## Process instance and scheme A [scheme](https://docs.workflowengine.io/get-started/concepts/scheme/) is the blueprint; a process instance is an execution based on that blueprint. Workflow Engine creates many process instances from the same scheme, each tracking its own state independently. When the scheme is updated, existing instances continue running against the scheme version they started with, and can be migrated to a new version on demand. ### Accessing the scheme from a process instance Every process instance holds a reference to its scheme definition. Use this to inspect the scheme's activities, transitions, and other elements at runtime: ```csharp // Access the scheme from the process instance var scheme = processInstance.ProcessScheme; // List all activities List activities = scheme.Activities; // Find the initial activity ActivityDefinition initial = scheme.InitialActivity; // Find a specific activity by name ActivityDefinition review = scheme.FindActivity("Review"); // List all transitions List transitions = scheme.Transitions; // Find a specific transition TransitionDefinition transition = scheme.FindTransition("ApproveReview"); ``` ### Accessing current state through WorkflowRuntime Without loading the full process instance, query the current state directly: ```csharp // Quick queries without loading the full instance string activityName = await runtime.GetCurrentActivityNameAsync(processId); string stateName = await runtime.GetCurrentStateNameAsync(processId); ProcessStatus status = await runtime.GetProcessStatusAsync(processId); ``` ## See also - [Scheme](https://docs.workflowengine.io/get-started/concepts/scheme/): A scheme defines the blueprint that each process instance follows. - [Activity](https://docs.workflowengine.io/get-started/concepts/activity/): Activities are the stable states where a process instance waits. - [Command](https://docs.workflowengine.io/get-started/concepts/command/): Commands move a process instance from one activity to another. - [Process Logs](https://docs.workflowengine.io/get-started/concepts/process-logs/): Process logs record events scoped to a single process instance. ## Frequently asked questions **What is a process instance in Workflow Engine?** A process instance is one execution of a scheme, created by Workflow Engine for a specific business process. Each instance has its own current activity, parameter values, and transition history, and is persisted independently in the database. **How do I create a process instance in Workflow Engine?** Create a process instance by calling `CreateInstanceAsync` with a scheme code and a unique identifier. Workflow Engine positions the new instance at the initial activity defined in the scheme and persists it to the database. You can also provide initial parameter values to set business data at creation time. **Can a process instance move backwards to a previous activity?** A process instance can move backwards only if a transition to that previous activity exists in the scheme. If no transition leads back to the target activity, the instance cannot move there through normal execution. You can, however, set the process instance to a specific state if the target activity is configured to accept direct state changes. **How do I get the current activity of a process instance from application code?** Call `runtime.GetCurrentActivityNameAsync(processId)` for the activity name, or load the full instance with `runtime.GetProcessInstanceAndFillProcessParametersAsync(processId)` and read `processInstance.CurrentActivity` or `processInstance.CurrentState`. **What is the difference between CurrentState and ExecutedActivityState?** `CurrentState` is the last recorded business state. It remains unchanged until the process completes a transition to an activity with a different state. `ExecutedActivityState` is the state of the activity whose actions are currently executing. During action execution, these can differ.