{"record":{"id":"4c7c02eb6c89eff9","repo":"elsa-workflows/elsa-core","slug":"storage-unit-collection-name-requires-index-values-for","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.MongoDb/MongoDbDocumentStore.cs","lineNumber":161,"sourceCode":"        var exists = await cursor.MoveNextAsync(cancellationToken) && cursor.Current.Any();\n        if (!exists)\n            await _database.CreateCollectionAsync(collectionName, cancellationToken: cancellationToken);\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 static async Task<StoredDocument?> LoadDocumentAsync(IMongoCollection<BsonDocument> collection, string storageUnit, string id, CancellationToken cancellationToken)\n    {\n        var document = await collection.Find(Builders<BsonDocument>.Filter.Eq(\"_id\", id)).FirstOrDefaultAsync(cancellationToken);\n        return document is null ? null : ReadDocument(document, storageUnit);\n    }\n\n    private static FilterDefinition<BsonDocument> CreateSaveFilter(SaveDocumentRequest request)","sourceCodeStart":143,"sourceCodeEnd":179,"githubUrl":"https://github.com/elsa-workflows/elsa-core/blob/fe9217bdfa0e27f0e09e45006eb6898f616e513d/src/modules/Elsa.Persistence.VNext.MongoDb/MongoDbDocumentStore.cs#L143-L179","documentation":"SaveAsync requires the request to supply index values for every field defined across the collection's indexes. Missing fields would make it impossible to build the index entries MongoDB needs, so ValidateSaveRequest throws DocumentStoreValidationException listing the exact missing field names and the storage unit (collection) they belong to.","triggerScenarios":"Calling SaveAsync where collection.Indexes define field(s) that request.IndexValues does not contain (missing key, or key with different casing — the comparison is ordinal and case-sensitive).","commonSituations":"Adding a new indexed field to the collection schema without backfilling/supplying that field on existing write paths; renaming a field in the index definition while callers still use the old key; case mismatch like 'OrderId' vs 'orderId'.","solutions":["Add the missing field(s) named in the message to request.IndexValues before calling SaveAsync.","Compare field names exactly (ordinal, case-sensitive) between collection.Indexes field definitions and your IndexValues keys.","If the index definition changed, update all writers or write a migration that populates the new index value for documents."],"exampleFix":"// before\nvar request = new SaveDocumentRequest { Id = id, IndexValues = new Dictionary<string, string?> { [\"orderId\"] = orderId } };\n\n// after (collection indexes on orderId and customerEmail)\nvar request = new SaveDocumentRequest { Id = id, IndexValues = new Dictionary<string, string?> { [\"orderId\"] = orderId, [\"customerEmail\"] = customerEmail } };","handlingStrategy":"validation","validationCode":"var requiredFields = collection.Indexes.SelectMany(i => i.Fields).Distinct(StringComparer.Ordinal).ToList();\nvar missing = requiredFields.Where(f => !request.IndexValues.ContainsKey(f)).ToList();\nif (missing.Count > 0)\n    throw new InvalidOperationException($\"Missing index values: {string.Join(\", \", missing)}\");","typeGuard":null,"tryCatchPattern":"try\n{\n    await store.SaveAsync(collection, request, ct);\n}\ncatch (DocumentStoreValidationException ex)\n{\n    logger.LogError(ex, \"Missing index values for storage unit {Unit}\", collection.Name);\n    throw;\n}","preventionTips":["Derive IndexValues keys from the same source of truth as the index definitions; never hard-code field names twice.","Remember key comparison is ordinal/case-sensitive — match field names exactly.","When adding an indexed field, update all write paths and backfill in the same change."],"tags":["mongodb","validation","persistence","index-values"],"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"}