elsa-workflows/elsa-core · error · InvalidOperationException
Runtime entity definition
Error message
Runtime entity definition '{definition.Name}' declares field '{duplicateField.Key}' more than once. What it means
Field names within a runtime entity definition must be unique, compared case-insensitively (OrdinalIgnoreCase). Validate groups fields by name and throws when any name appears more than once, since duplicate names make storage and index mapping ambiguous.
Solutions
- Remove or rename the duplicated field so names are unique ignoring case.
- Deduplicate the field list before validation, e.g. GroupBy(x => x.Name, StringComparer.OrdinalIgnoreCase) and keep one.
- If a default field set is merged with user fields, skip defaults whose names already exist.
Example fix
// before
def.Fields.Add(new RuntimeEntityField { Name = "Status" });
def.Fields.Add(new RuntimeEntityField { Name = "status" }); // duplicate ignoring case
// after
def.Fields.Add(new RuntimeEntityField { Name = "Status" }); Defensive patterns
Strategy: validation
Validate before calling
var dupes = definition.Fields.GroupBy(f => f.Name, StringComparer.OrdinalIgnoreCase).Where(g => g.Count() > 1).Select(g => g.Key).ToList();
if (dupes.Count > 0) throw new InvalidOperationException($"Duplicate fields: {string.Join(", ", dupes)}"); Try / catch
try { validator.Validate(definition); }
catch (InvalidOperationException ex) { logger.LogError(ex, "Duplicate fields in {Name}", definition.Name); throw; } Prevention
- Deduplicate fields at build/merge time with GroupBy(OrdinalIgnoreCase).
- When merging defaults with user fields, skip already-present names.
- Normalize field-name casing in configuration binding.
When it happens
Trigger: Calling Validate where two or more Fields entries share the same name ignoring case — e.g. 'Status' and 'status'.
Common situations: Merging field lists from multiple configuration sources; appending default fields without checking whether the user already declared them; case differences from copy-paste or JSON config with case-insensitive consumers.
Understand the failure class
Background: Schema validation failed / invalid input schema: payload rejected because its shape doesn't match the expected schema — this error's family across 28 libraries.
Related errors
- Runtime entity definition
- Runtime entity definition
- Runtime entity definition
- Runtime entity definition name is required.
- Runtime entity instance
AI-assisted analysis of elsa-workflows/elsa-core@fe9217bdfa (2026-09-13).
Data as JSON: /api/errors/8981478f4692095d.
Report an issue: GitHub.
Appendix: source
Thrown at src/modules/Elsa.Persistence.VNext.Runtime/Services/RuntimeEntityDefinitionValidator.cs:18
using Elsa.Persistence.VNext.Runtime.Models;
using Microsoft.Extensions.Options;
namespace Elsa.Persistence.VNext.Runtime.Services;
public class RuntimeEntityDefinitionValidator(IOptions<RuntimeEntityOptions> options)
{
public void Validate(RuntimeEntityDefinition definition)
{
if (string.IsNullOrWhiteSpace(definition.Name))
throw new InvalidOperationException("Runtime entity definition name is required.");
if (definition.Fields.Count == 0)
throw new InvalidOperationException($"Runtime entity definition '{definition.Name}' must declare at least one field.");
var duplicateField = definition.Fields.GroupBy(x => x.Name, StringComparer.OrdinalIgnoreCase).FirstOrDefault(x => x.Count() > 1);
if (duplicateField is not null)
throw new InvalidOperationException($"Runtime entity definition '{definition.Name}' declares field '{duplicateField.Key}' more than once.");
var maxIndexedFields = Math.Min(options.Value.MaxIndexedFields, RuntimeEntityPersistenceSchemaProvider.IndexedFieldSlotCount);
if (definition.Indexes.Count > maxIndexedFields)
throw new InvalidOperationException($"Runtime entity definition '{definition.Name}' declares {definition.Indexes.Count} indexes, but only {maxIndexedFields} runtime index slots are available.");
var fields = definition.Fields.Select(x => x.Name).ToHashSet(StringComparer.OrdinalIgnoreCase);
foreach (var index in definition.Indexes)
{
if (!fields.Contains(index.FieldName))
throw new InvalidOperationException($"Runtime entity definition '{definition.Name}' index '{index.Name}' references unknown field '{index.FieldName}'.");
}
}
public void ValidateInstance(RuntimeEntityDefinition definition, RuntimeEntityInstance instance)
{
var dataKeys = instance.Data.Keys.ToHashSet(StringComparer.OrdinalIgnoreCase);
var missingField = definition.Fields.FirstOrDefault(x => x.IsRequired && !dataKeys.Contains(x.Name));
if (missingField is not null)View on GitHub (pinned to fe9217bdfa)