{"record":{"id":"7e7e97ddbb1ac350","repo":"elsa-workflows/elsa-core","slug":"string-join-failures","errorCode":null,"errorMessage":"{string.Join(\" \", failures)}","messagePattern":"\\{string\\.Join\\(\" \", failures\\)\\}","errorType":"validation","errorClass":"InvalidOperationException","httpStatus":null,"severity":"error","filePath":"src/modules/Elsa.ExternalAuthentication/Services/ExtensionDescriptorValidator.cs","lineNumber":75,"sourceCode":"        if (!IsIdentifier(extensionType))\n            failures.Add($\"Extension type '{extensionType}' is not a stable identifier.\");\n        if (!string.Equals(extensionType, descriptorType, StringComparison.Ordinal))\n            failures.Add($\"Descriptor type '{descriptorType}' does not match extension type '{extensionType}'.\");\n        if (string.IsNullOrWhiteSpace(displayName))\n            failures.Add($\"Extension '{extensionType}' must define a display name.\");\n        if (string.IsNullOrWhiteSpace(description))\n            failures.Add($\"Extension '{extensionType}' must define a description.\");\n        if (settingsVersion <= 0)\n            failures.Add($\"Extension '{extensionType}' must define a positive settings version.\");\n        if (fields is null)\n            failures.Add($\"Extension '{extensionType}' must define a fields collection.\");\n        else\n            ValidateFields(extensionType, fields, failures);\n        if (customEditor is not null && (!IsIdentifier(customEditor.Key) || customEditor.ContractVersion <= 0))\n            failures.Add($\"Extension '{extensionType}' has an invalid custom-editor contract.\");\n\n        if (failures.Count > 0)\n            throw new InvalidOperationException(string.Join(\" \", failures));\n    }\n\n    private static void ValidateFields(string extensionType, IReadOnlyCollection<SettingFieldDescriptor> fields, ICollection<string> failures)\n    {\n        var names = new HashSet<string>(StringComparer.Ordinal);\n        foreach (var field in fields)\n        {\n            if (!IsSettingFieldName(field.Name))\n                failures.Add($\"Extension '{extensionType}' has invalid field name '{field.Name}'.\");\n            else if (!names.Add(field.Name))\n                failures.Add($\"Extension '{extensionType}' defines field '{field.Name}' more than once.\");\n            if (string.IsNullOrWhiteSpace(field.DisplayName) || string.IsNullOrWhiteSpace(field.Description))\n                failures.Add($\"Field '{field.Name}' must define display text.\");\n            if (!SupportedValueTypes.Contains(field.ValueType))\n                failures.Add($\"Field '{field.Name}' has unsupported value type '{field.ValueType}'.\");\n            if (string.IsNullOrWhiteSpace(field.UiHint))\n                failures.Add($\"Field '{field.Name}' must define a UI hint.\");\n            if (field.Validation.MinimumLength is < 0 ||","sourceCodeStart":57,"sourceCodeEnd":93,"githubUrl":"https://github.com/elsa-workflows/elsa-core/blob/fe9217bdfa0e27f0e09e45006eb6898f616e513d/src/modules/Elsa.ExternalAuthentication/Services/ExtensionDescriptorValidator.cs#L57-L93","documentation":"A validation guard thrown by ExtensionDescriptorValidator.ValidateDescriptor: the extension descriptor failed one or more structural checks (identifier not a stable name, descriptor/extension type mismatch, missing display name or description, etc.), and the aggregated failure list is joined into the exception message.","triggerScenarios":"Thrown at src/modules/Elsa.ExternalAuthentication/Services/ExtensionDescriptorValidator.cs:75 when the library encounters an invalid state.","commonSituations":"See trigger scenarios.","solutions":["Fix each listed failure: give the extension a stable identifier type name, matching descriptor type, non-empty display name and description.","Validate descriptors at startup or in tests so misconfigured extensions are caught before registration.","Compare against a known-good ExtensionDescriptor in the same feature for the expected shape."],"exampleFix":null,"handlingStrategy":"validation","validationCode":null,"typeGuard":null,"tryCatchPattern":null,"preventionTips":[],"tags":[],"backgroundTag":null,"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"}