{"record":{"id":"3aa7620081428ebb","repo":"elsa-workflows/elsa-core","slug":"bpmn-element-unbound-elementid-of-process-unbound-processid","errorCode":null,"errorMessage":"BPMN element '{unbound.ElementId}' of process '{unbound.ProcessId}' is a '{unbound.TaskType}': the document says what it is for, not how to perform it, and nothing binds it to an Elsa activity. Declare one with an <{BpmnActivityBindingFormat.NamespacePrefix}:{BpmnActivityBindingFormat.BindingElementName}> element inside the element's <extensionElements>.","messagePattern":"BPMN element '(.+?)' of process '(.+?)' is a '(.+?)': the document says what it is for, not how to perform it, and nothing binds it to an Elsa activity\\. Declare one with an <(.+?):(.+?)> element inside the element's <extensionElements>\\.","errorType":"exception","errorClass":"BpmnBindingException","httpStatus":null,"severity":"error","filePath":"src/modules/Elsa.Bpmn.Interchange/Binding/BpmnWorkBinder.cs","lineNumber":144,"sourceCode":"            BpmnWorkBinding.CallProcess call => new DispatchWorkflow\n            {\n                WorkflowDefinitionId = new(CalledElementOf(call)),\n                WaitForCompletion = new(call.WaitForCompletion)\n            },\n            BpmnWorkBinding.NestedProcess nested => BindScope(nested.Definition, bindings),\n            BpmnWorkBinding.UnboundTask unbound => ReadDeclaredActivity(definition, unbound, consumed),\n            // The binding hierarchy is closed, so this is reachable only from a library version that added a kind this\n            // binder has never heard of. Skipping it would produce a scope whose interpreter starts work nothing maps.\n            _ => throw new BpmnBindingException($\"The BPMN work binding kind '{binding.GetType().Name}' declared by element '{binding.ElementId}' is not supported by this binder.\")\n        };\n\n    private IActivity ReadDeclaredActivity(BpmnProcessDefinition definition, BpmnWorkBinding.UnboundTask unbound, ISet<string> consumed)\n    {\n        var element = definition.Elements.FirstOrDefault(element => string.Equals(element.ElementId, unbound.ElementId, StringComparison.Ordinal));\n\n        if (BpmnActivityBindingFormat.Find(element?.Extensions) is not { } declaration)\n        {\n            throw new BpmnBindingException(\n                $\"BPMN element '{unbound.ElementId}' of process '{unbound.ProcessId}' is a '{unbound.TaskType}': the document says what it is for, not how to perform it, and nothing binds it to an Elsa activity. \"\n                + $\"Declare one with an <{BpmnActivityBindingFormat.NamespacePrefix}:{BpmnActivityBindingFormat.BindingElementName}> element inside the element's <extensionElements>.\");\n        }\n\n        consumed.Add(unbound.ElementId);\n\n        return format.Read(declaration);\n    }\n\n    /// <summary>\n    /// Refuses an <c>elsa:activityBinding</c> on an element that has no unbound task to bind.\n    /// </summary>\n    /// <remarks>\n    /// Six of the seven kinds bind on their own and never consult a declaration, so one written on a timer, a\n    /// subprocess or a gateway configures nothing. Ignoring it is the quiet answer: the author sees their expression in\n    /// the file, the process runs, and the activity they configured never executes. Refusing says so.\n    /// </remarks>\n    private static void RefuseUnusedDeclarations(BpmnProcessDefinition definition, ISet<string> consumed)","sourceCodeStart":126,"sourceCodeEnd":162,"githubUrl":"https://github.com/elsa-workflows/elsa-core/blob/fe9217bdfa0e27f0e09e45006eb6898f616e513d/src/modules/Elsa.Bpmn.Interchange/Binding/BpmnWorkBinder.cs#L126-L162","documentation":"A BPMN task element is described as an 'unbound task' — the document says what it is for but not how to perform it — and no <elsa:binding> declaration was found in its <extensionElements>. The binder cannot construct any activity for it, so import fails with guidance on how to declare one.","triggerScenarios":"BpmnWorkBinder.ReadDeclaredActivity (via CreateActivity for an UnboundTask binding) finds BpmnActivityBindingFormat.Find(element.Extensions) returns null for the element with the given ElementId.","commonSituations":"Authoring a .bpmn by hand or in a generic BPMN tool and forgetting the Elsa extension binding; the binding element placed outside <extensionElements>; element ID mismatch after renaming IDs in the modeler.","solutions":["Add an <elsa:binding> element (with activityType and <elsa:input> children) inside the task's <bpmn:extensionElements>.","Verify the binding is attached to the element whose id matches the one named in the error, inside that element's <extensionElements>.","If the task should not run in Elsa, change the BPMN so it is not an unbound task (e.g. map it to a supported BPMN construct)."],"exampleFix":"// before\n<bpmn:serviceTask id=\"Task1\" name=\"Send email\" />\n// after\n<bpmn:serviceTask id=\"Task1\" name=\"Send email\">\n  <bpmn:extensionElements>\n    <elsa:binding activityType=\"SendEmail\">\n      <elsa:input name=\"Subject\">\"Hello\"</elsa:input>\n    </elsa:binding>\n  </bpmn:extensionElements>\n</bpmn:serviceTask>","handlingStrategy":"validation","validationCode":"foreach (var task in doc.Descendants().Where(e => e.Name.LocalName.EndsWith(\"Task\")))\n{\n    var hasBinding = task.Element(\"extensionElements\")?.Elements().Any(x => x.Name.LocalName == \"binding\") == true;\n    if (!hasBinding) Console.WriteLine($\"Task {task.Attribute(\"id\")?.Value} has no elsa:binding and will fail import if unbound.\");\n}","typeGuard":"static bool HasElsaBinding(XElement element) =>\n    element.Element(\"extensionElements\")?.Elements()\n        .Any(x => x.Name.LocalName == \"binding\" && x.Name.Namespace.NamespaceName.StartsWith(\"urn:elsa\")) == true;","tryCatchPattern":"try { await importer.ImportAsync(bpmn); }\ncatch (BpmnBindingException ex) when (ex.Message.Contains(\"nothing binds it to an Elsa activity\"))\n{\n    logger.LogError(ex, \"Declare an <elsa:binding> in the task's <extensionElements>.\");\n}","preventionTips":["Adopt a checklist: every authored task in a .bpmn must carry an <elsa:binding>","Use a modeler template or snippet that includes the extensionElements block","Verify element ids match between the task and its binding"],"tags":["bpmn","missing-binding","unbound-task"],"backgroundTag":"missing-required-config-field","analyzedSha":"fe9217bdfa0e27f0e09e45006eb6898f616e513d","analyzedAt":"2026-09-13T20:32:34.702Z","contentChangedAt":"2026-09-13T20:32:34.702Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}