{"record":{"id":"6c53f5c36bc2cec4","repo":"elsa-workflows/elsa-core","slug":"storage-unit-collection-name-requires-index-values-for-6c53f5","errorCode":null,"errorMessage":"Storage unit '{collection.Name}' requires index values for fields '{string.Join(\", \", missingFields)}'.","messagePattern":"Storage unit '(.+?)' requires index values for fields '(.+?)'\\.","errorType":"validation","errorClass":"DocumentStoreValidationException","httpStatus":null,"severity":"error","filePath":"src/modules/Elsa.Persistence.VNext.Relational/Documents/RelationalDocumentStore.cs","lineNumber":129,"sourceCode":"    {\n        return _plan.Collections.SingleOrDefault(x => string.Equals(x.Name, storageUnit, StringComparison.Ordinal))\n            ?? throw new DocumentStoreValidationException($\"Storage unit '{storageUnit}' is not declared in the persistence schema.\");\n    }\n\n    private static void ValidateSaveRequest(DocumentCollection collection, SaveDocumentRequest request)\n    {\n        if (string.IsNullOrWhiteSpace(request.Id))\n            throw new DocumentStoreValidationException(\"Document ID is required.\");\n\n        var missingFields = collection.Indexes\n            .SelectMany(x => x.Fields)\n            .Distinct(StringComparer.Ordinal)\n            .Where(field => !request.IndexValues.ContainsKey(field))\n            .Order(StringComparer.Ordinal)\n            .ToList();\n\n        if (missingFields.Count > 0)\n            throw new DocumentStoreValidationException($\"Storage unit '{collection.Name}' requires index values for fields '{string.Join(\", \", missingFields)}'.\");\n    }\n\n    private static void ValidateExpectedVersion(string storageUnit, string documentId, long? expectedVersion, long? actualVersion)\n    {\n        if (expectedVersion is null)\n            return;\n\n        if (expectedVersion != (actualVersion ?? 0))\n            throw new DocumentStoreConcurrencyException(storageUnit, documentId, expectedVersion, actualVersion);\n    }\n\n    private async Task OpenAsync(CancellationToken cancellationToken)\n    {\n        if (_connection.State != ConnectionState.Open)\n            await _connection.OpenAsync(cancellationToken);\n    }\n\n    private async Task<StoredDocument?> LoadAsync(DbTransaction? transaction, string storageUnit, string id, CancellationToken cancellationToken)","sourceCodeStart":111,"sourceCodeEnd":147,"githubUrl":"https://github.com/elsa-workflows/elsa-core/blob/fe9217bdfa0e27f0e09e45006eb6898f616e513d/src/modules/Elsa.Persistence.VNext.Relational/Documents/RelationalDocumentStore.cs#L111-L147","documentation":"Every field covered by a declared index on a storage unit must be supplied as an index value in the save request, since these values populate physical index columns. SaveAsync collects all missing indexed fields and reports them in one DocumentStoreValidationException.","triggerScenarios":"Calling SaveAsync where request.IndexValues lacks a key for at least one field referenced by collection.Indexes.","commonSituations":"Adding a new index to the schema without backfilling/producing the corresponding index value in save code; field-name casing mismatch (keys are compared with ContainsKey, case-sensitive); saving an older document shape against an updated schema.","solutions":["Add values for every missing field listed in the message to request.IndexValues before saving.","Compare index field names in the schema with the keys you populate — names must match exactly.","If the index is new, backfill existing documents and update the save path to emit the new index values.","Make index-value population derive from the same constant/property used to declare the index so they cannot diverge."],"exampleFix":"// before\nvar request = new SaveDocumentRequest { Id = doc.Id, Data = doc, IndexValues = { [\"CorrelationId\"] = doc.CorrelationId } };\n// after\nvar request = new SaveDocumentRequest { Id = doc.Id, Data = doc, IndexValues = { [\"CorrelationId\"] = doc.CorrelationId, [\"Status\"] = doc.Status } }; // Status is an indexed field","handlingStrategy":"validation","validationCode":"var missing = collection.Indexes.SelectMany(i => i.Fields).Distinct()\n    .Where(f => !request.IndexValues.ContainsKey(f)).ToList();\nif (missing.Count > 0) throw new InvalidOperationException($\"Missing index values: {string.Join(\", \", missing)}\");","typeGuard":null,"tryCatchPattern":"try { await store.SaveAsync(collection, request); }\ncatch (DocumentStoreValidationException ex) { logger.LogError(ex, \"Index values incomplete for {Unit}\", collection.Name); throw; }","preventionTips":["Build IndexValues from the same constants used to declare indexes.","Backfill index values whenever an index is added to the schema.","Mirror schema changes in save-path code as a paired commit."],"tags":["persistence","validation","index"],"backgroundTag":"missing-required-argument","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"}