{"record":{"id":"41659f55105e73e6","repo":"elsa-workflows/elsa-core","slug":"we-lost-a-context-this-could-indicate-a-bug-in-a-parent","errorCode":null,"errorMessage":"We lost a context. This could indicate a bug in a parent activity that completed before (some of) its child activities.","messagePattern":"We lost a context\\. This could indicate a bug in a parent activity that completed before \\(some of\\) its child activities\\.","errorType":"exception","errorClass":"Exception","httpStatus":null,"severity":"critical","filePath":"src/modules/Elsa.Workflows.Core/Services/WorkflowStateExtractor.cs","lineNumber":301,"sourceCode":"        }\n\n        var completionCallbacks = workflowExecutionContext.CompletionCallbacks.Select(x => new CompletionCallbackState(x.Owner.Id, x.Child.NodeId, x.CompletionCallback?.Method.Name, x.Tag));\n\n        state.CompletionCallbacks = completionCallbacks.ToList();\n    }\n\n    private static void ExtractActiveActivityExecutionContexts(WorkflowState state, WorkflowExecutionContext workflowExecutionContext)\n    {\n        ActivityExecutionContextState CreateActivityExecutionContextState(ActivityExecutionContext activityExecutionContext)\n        {\n            var parentId = activityExecutionContext.ParentActivityExecutionContext?.Id;\n\n            if (parentId != null)\n            {\n                var parentContext = activityExecutionContext.WorkflowExecutionContext.ActivityExecutionContexts.FirstOrDefault(x => x.Id == parentId);\n\n                if (parentContext == null)\n                    throw new(\"We lost a context. This could indicate a bug in a parent activity that completed before (some of) its child activities.\");\n            }\n\n            var activityExecutionContextState = new ActivityExecutionContextState\n            {\n                Id = activityExecutionContext.Id,\n                CallStackDepth = activityExecutionContext.CallStackDepth,\n                ParentContextId = activityExecutionContext.ParentActivityExecutionContext?.Id,\n                ScheduledActivityNodeId = activityExecutionContext.NodeId,\n                OwnerActivityNodeId = activityExecutionContext.ParentActivityExecutionContext?.NodeId,\n                Properties = activityExecutionContext.Properties,\n                Metadata = activityExecutionContext.Metadata,\n                ActivityState = activityExecutionContext.ActivityState,\n                Status = activityExecutionContext.Status,\n                IsExecuting = activityExecutionContext.IsExecuting,\n                FaultCount = activityExecutionContext.AggregateFaultCount,\n                StartedAt = activityExecutionContext.StartedAt,\n                CompletedAt = activityExecutionContext.CompletedAt,\n                Tag = activityExecutionContext.Tag,","sourceCodeStart":283,"sourceCodeEnd":319,"githubUrl":"https://github.com/elsa-workflows/elsa-core/blob/fe9217bdfa0e27f0e09e45006eb6898f616e513d/src/modules/Elsa.Workflows.Core/Services/WorkflowStateExtractor.cs#L283-L319","documentation":"While extracting the state of active activity execution contexts, the extractor records each context's parent ID and verifies the parent still exists in the workflow execution context's collection. A missing parent means a parent activity's context was completed/removed while its child contexts remained active — an inconsistency that would produce unrestorable state — so the extractor throws with this diagnostic message.","triggerScenarios":"Extract/persist/suspend a workflow instance when an active ActivityExecutionContext references a ParentContext ID that is no longer present in WorkflowExecutionContext.ActivityExecutionContexts — typically a parent activity completed before some of its children.","commonSituations":"Buggy custom or composite activities calling Complete() before all child contexts finished; race between parent completion and child scheduling; older Elsa versions with known parent-completion bugs in parallel/flow activities; resuming after partial state corruption.","solutions":["Fix the offending parent activity to remain active until every child activityExecutionContext completes (defer completion until all children's callbacks/contexts are done).","Update to the latest Elsa packages; several parent-completes-too-early bugs in built-in activities have been patched.","Review custom activities for early context.Complete()/broken completion-callback wiring and use context.DeferCallbacks where children are scheduled.","Identify the guilty activity from the exception context/logs and restructure the workflow (e.g. use a Parallel/Flowchart with correct completion semantics).","If persisting mid-execution, ensure extraction happens only at safe suspension points where parent/child contexts are consistent."],"exampleFix":"// before (parent activity ExecuteAsync)\nforeach (var child in children) context.ScheduleActivity(child);\ncontext.Complete(); // parent context dies before children -> lost parent\n// after\nforeach (var child in children)\n    context.ScheduleActivity(child, completionCallback: _ =>\n    {\n        if (context.GetActivityExecutionContextCount() == 0) // or track pending children\n            context.Complete();\n    });","handlingStrategy":"try-catch","validationCode":"var activeIds = context.GetActiveActivityExecutionContexts().Select(x => x.Id).ToHashSet();\nbool parentsConsistent = context.GetActiveActivityExecutionContexts().All(x => x.ParentContext == null || activeIds.Contains(x.ParentContext.Id));","typeGuard":null,"tryCatchPattern":"try { var state = extractor.Extract(context); } catch (Exception ex) { logger.LogCritical(ex, \"State extraction failed: parent activity completed before children (workflow {InstanceId})\", context.Id); throw; }","preventionTips":["Never call Complete() on a parent activity before all child completion callbacks run","Use DeferCallbacks when scheduling children whose completion must precede parent completion","Keep Elsa packages updated; several parent-completion bugs are fixed in newer releases","Test suspend/resume of workflows containing composites and parallel activities"],"tags":["state-extraction","activity-contexts","csharp"],"backgroundTag":"internal-invariant-violation","analyzedSha":"fe9217bdfa0e27f0e09e45006eb6898f616e513d","analyzedAt":"2026-09-13T20:32:34.702Z","contentChangedAt":"2026-09-13T20:32:34.702Z","schemaVersion":2},"datasetVersion":"2026-09-15T23:17:13.987Z"}