{"record":{"id":"8065ed36b98de3fc","repo":"elsa-workflows/elsa-core","slug":"the-activitytype-binding-declares-noun-names-which","errorCode":null,"errorMessage":"The '{activityType}' binding declares {noun} {names}, which '{activityType}' does not have.","messagePattern":"The '(.+?)' binding declares (.+?) (.+?), which '(.+?)' does not have\\.","errorType":"exception","errorClass":"BpmnBindingException","httpStatus":null,"severity":"error","filePath":"src/modules/Elsa.Bpmn.Interchange/Binding/BpmnActivityBindingFormat.cs","lineNumber":252,"sourceCode":"        // Elsa's own JSON deserialization ignores a member the target type does not declare, so a mistyped or\n        // stale input name would otherwise import silently as an activity missing that configuration, with no\n        // diagnostic anywhere. IActivityDescriber.GetInputProperties is the same enumeration Write reads from and\n        // ActivityDescriptor.Inputs is built from, so a name is accepted here exactly when Write could have produced\n        // it.\n        if (seenInputNames.Count > 0)\n        {\n            var declaredInputNames = activityDescriber.GetInputProperties(activity.GetType())\n                .Select(property => JsonNamingPolicy.CamelCase.ConvertName(property.Name))\n                .ToHashSet(StringComparer.Ordinal);\n\n            var undeclaredInputNames = seenInputNames.Where(name => !declaredInputNames.Contains(name)).ToList();\n\n            if (undeclaredInputNames.Count > 0)\n            {\n                var noun = undeclaredInputNames.Count == 1 ? \"an input\" : \"inputs\";\n                var names = string.Join(\", \", undeclaredInputNames.Select(name => $\"'{name}'\"));\n\n                throw new BpmnBindingException($\"The '{activityType}' binding declares {noun} {names}, which '{activityType}' does not have.\");\n            }\n        }\n\n        return activity;\n    }\n\n    private static JsonNode? Parse(string? json, string inputName, string activityType)\n    {\n        try\n        {\n            return JsonNode.Parse(json ?? \"null\");\n        }\n        catch (JsonException exception)\n        {\n            throw new BpmnBindingException($\"Input '{inputName}' of the '{activityType}' binding does not hold valid JSON: {exception.Message}\");\n        }\n    }\n","sourceCodeStart":234,"sourceCodeEnd":270,"githubUrl":"https://github.com/elsa-workflows/elsa-core/blob/fe9217bdfa0e27f0e09e45006eb6898f616e513d/src/modules/Elsa.Bpmn.Interchange/Binding/BpmnActivityBindingFormat.cs#L234-L270","documentation":"The binding declares input(s) that the target activity type does not define. Elsa ignores unknown JSON members during deserialization, so this check at import time prevents silent loss of configuration.","triggerScenarios":"BpmnActivityBindingFormat.Read compares the declared input names against IActivityDescriber.GetInputProperties for the activity type and finds names not in that set (undeclaredInputNames.Count > 0).","commonSituations":"Misspelled input names in hand-written binding XML; stale bindings after a module rename/upgrade; copying a binding from another activity type.","solutions":["Remove the named input elements from the binding if they are not real inputs.","Correct the input names to match the activity type's declared inputs (check IActivityDescriber / ActivityDescriptor.Inputs).","If the input was removed in a newer module version, update the binding to the renamed property."],"exampleFix":"// before\n<elsa:binding activityType=\"SendEmail\">\n  <elsa:input name=\"Subjekt\">\"Hi\"</elsa:input>  // typo\n</elsa:binding>\n// after\n<elsa:binding activityType=\"SendEmail\">\n  <elsa:input name=\"Subject\">\"Hi\"</elsa:input>\n</elsa:binding>","handlingStrategy":"validation","validationCode":"var declared = activityDescriptor.Inputs.Select(i => i.Name).ToHashSet();\nvar unknown = bindingInputs.Where(i => !declared.Contains(i)).ToList();\nif (unknown.Any()) throw new InvalidOperationException($\"Inputs not declared on activity: {string.Join(\", \", unknown)}\");","typeGuard":null,"tryCatchPattern":"try { await importer.ImportAsync(bpmn); }\ncatch (BpmnBindingException ex) when (ex.Message.Contains(\"does not have\"))\n{\n    logger.LogError(ex, \"Binding names inputs the activity type does not declare; fix or remove them.\");\n}","preventionTips":["Source input names from the activity descriptor, not from memory","Re-check bindings after renaming or upgrading activity types","Diff the binding input names against the activity's descriptor when reviewing BPMN PRs"],"tags":["bpmn","validation","unknown-input"],"backgroundTag":"schema-validation-failed","analyzedSha":"fe9217bdfa0e27f0e09e45006eb6898f616e513d","analyzedAt":"2026-09-13T20:32:34.702Z","contentChangedAt":"2026-09-13T20:32:34.702Z","schemaVersion":2},"datasetVersion":"2026-09-16T04:17:20.429Z"}