{"record":{"id":"bccb0868cf729802","repo":"elsa-workflows/elsa-core","slug":"runtime-entity-definition-definition-name-declares","errorCode":null,"errorMessage":"Runtime entity definition '{definition.Name}' declares {definition.Indexes.Count} indexes, but only {maxIndexedFields} runtime index slots are available.","messagePattern":"Runtime entity definition '(.+?)' declares (.+?) indexes, but only (.+?) runtime index slots are available\\.","errorType":"validation","errorClass":"InvalidOperationException","httpStatus":null,"severity":"error","filePath":"src/modules/Elsa.Persistence.VNext.Runtime/Services/RuntimeEntityDefinitionValidator.cs","lineNumber":22,"sourceCode":"namespace Elsa.Persistence.VNext.Runtime.Services;\n\npublic class RuntimeEntityDefinitionValidator(IOptions<RuntimeEntityOptions> options)\n{\n    public void Validate(RuntimeEntityDefinition definition)\n    {\n        if (string.IsNullOrWhiteSpace(definition.Name))\n            throw new InvalidOperationException(\"Runtime entity definition name is required.\");\n\n        if (definition.Fields.Count == 0)\n            throw new InvalidOperationException($\"Runtime entity definition '{definition.Name}' must declare at least one field.\");\n\n        var duplicateField = definition.Fields.GroupBy(x => x.Name, StringComparer.OrdinalIgnoreCase).FirstOrDefault(x => x.Count() > 1);\n        if (duplicateField is not null)\n            throw new InvalidOperationException($\"Runtime entity definition '{definition.Name}' declares field '{duplicateField.Key}' more than once.\");\n\n        var maxIndexedFields = Math.Min(options.Value.MaxIndexedFields, RuntimeEntityPersistenceSchemaProvider.IndexedFieldSlotCount);\n        if (definition.Indexes.Count > maxIndexedFields)\n            throw new InvalidOperationException($\"Runtime entity definition '{definition.Name}' declares {definition.Indexes.Count} indexes, but only {maxIndexedFields} runtime index slots are available.\");\n\n        var fields = definition.Fields.Select(x => x.Name).ToHashSet(StringComparer.OrdinalIgnoreCase);\n        foreach (var index in definition.Indexes)\n        {\n            if (!fields.Contains(index.FieldName))\n                throw new InvalidOperationException($\"Runtime entity definition '{definition.Name}' index '{index.Name}' references unknown field '{index.FieldName}'.\");\n        }\n    }\n\n    public void ValidateInstance(RuntimeEntityDefinition definition, RuntimeEntityInstance instance)\n    {\n        var dataKeys = instance.Data.Keys.ToHashSet(StringComparer.OrdinalIgnoreCase);\n        var missingField = definition.Fields.FirstOrDefault(x => x.IsRequired && !dataKeys.Contains(x.Name));\n        if (missingField is not null)\n            throw new InvalidOperationException($\"Runtime entity instance '{instance.Id}' is missing required field '{missingField.Name}'.\");\n    }\n}\n","sourceCodeStart":4,"sourceCodeEnd":40,"githubUrl":"https://github.com/elsa-workflows/elsa-core/blob/fe9217bdfa0e27f0e09e45006eb6898f616e513d/src/modules/Elsa.Persistence.VNext.Runtime/Services/RuntimeEntityDefinitionValidator.cs#L4-L40","documentation":"The number of declared indexes on a runtime entity definition is capped by MaxIndexedFields (from options) and by the physical slot count exposed by RuntimeEntityPersistenceSchemaProvider.IndexedFieldSlotCount — Validate uses the smaller of the two. Exceeding it throws, because the storage layout only materializes that many runtime index columns.","triggerScenarios":"Calling Validate where definition.Indexes.Count exceeds min(options.MaxIndexedFields, RuntimeEntityPersistenceSchemaProvider.IndexedFieldSlotCount).","commonSituations":"Lowering MaxIndexedFields in configuration below a previously valid definition; adding many indexes as a document evolves; a storage provider with fewer physical slots than the definition assumes.","solutions":["Trim definition.Indexes to the most essential fields so the count fits the limit.","Raise RuntimeEntityOptions.MaxIndexedFields in configuration, if the physical slot count also allows it.","Drop low-value indexes (rarely filtered fields) and rely on scans for those queries instead."],"exampleFix":"// before\noptions.MaxIndexedFields = 5; // definition declares 8 indexes\n// after\noptions.MaxIndexedFields = 10; // or reduce definition.Indexes to 5","handlingStrategy":"validation","validationCode":"var max = Math.Min(options.MaxIndexedFields, RuntimeEntityPersistenceSchemaProvider.IndexedFieldSlotCount);\nif (definition.Indexes.Count > max) throw new InvalidOperationException($\"{definition.Indexes.Count} indexes exceeds limit {max}.\");","typeGuard":null,"tryCatchPattern":"try { validator.Validate(definition); }\ncatch (InvalidOperationException ex) { logger.LogError(ex, \"Too many indexes on {Name}\", definition.Name); throw; }","preventionTips":["Keep MaxIndexedFields configuration in sync with the storage provider's slot count.","Review index lists whenever a definition gains fields.","Prefer few high-selectivity indexes over exhaustive indexing."],"tags":["validation","runtime-entities","index-limits"],"backgroundTag":"value-out-of-range","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"}