{"record":{"id":"019c2599ee4e3e36","repo":"dotnet/orleans","slug":"too-many-rows-for-bulk-update-max-this-storagep","errorCode":null,"errorMessage":"Too many rows for bulk update - max {this.StoragePolicyOptions.MaxBulkUpdateRows}","messagePattern":"Too many rows for bulk update - max (.+?)","errorType":"exception","errorClass":"ArgumentOutOfRangeException","httpStatus":null,"severity":"error","filePath":"src/Azure/Shared/Storage/AzureTableDataManager.cs","lineNumber":572,"sourceCode":"            finally\n            {\n                CheckAlertSlowAccess(startTime, operation);\n            }\n        }\n\n        /// <summary>\n        /// Inserts a set of new data entries into the table.\n        /// Fails if the data does already exists.\n        /// </summary>\n        /// <param name=\"collection\">Data entries to be inserted into the table.</param>\n        /// <returns>Completion promise for this storage operation.</returns>\n        public async Task BulkInsertTableEntries(IReadOnlyCollection<T> collection)\n        {\n            const string operation = \"BulkInsertTableEntries\";\n            if (collection == null) throw new ArgumentNullException(nameof(collection));\n            if (collection.Count > this.StoragePolicyOptions.MaxBulkUpdateRows)\n            {\n                throw new ArgumentOutOfRangeException(nameof(collection), collection.Count,\n                        \"Too many rows for bulk update - max \" + this.StoragePolicyOptions.MaxBulkUpdateRows);\n            }\n\n            if (collection.Count == 0)\n            {\n                return;\n            }\n\n            var startTime = DateTime.UtcNow;\n            LogTraceTableEntriesCount(Logger, operation, collection.Count, TableName);\n            try\n            {\n                var entityBatch = new List<TableTransactionAction>(collection.Count);\n                foreach (T entry in collection)\n                {\n                    entityBatch.Add(new TableTransactionAction(TableTransactionActionType.Add, entry));\n                }\n","sourceCodeStart":554,"sourceCodeEnd":590,"githubUrl":"https://github.com/dotnet/orleans/blob/fca799fa70ecb6ad975224271703ca43221f58de/src/Azure/Shared/Storage/AzureTableDataManager.cs#L554-L590","documentation":"ArgumentOutOfRangeException thrown when the collection passed to BulkInsertTableEntries has more rows than AzureStoragePolicyOptions.MaxBulkUpdateRows (default 100). The limit reflects the Azure Table Storage entity-group transaction cap of 100 operations per batch, so the library refuses an oversized single transaction up front.","triggerScenarios":"Passing a collection whose Count exceeds MaxBulkUpdateRows. The check is on IReadOnlyCollection.Count, so any materialized list/enumerable over the configured limit triggers it before any storage call.","commonSituations":"Bulk-importing reminders/membership/grain-directory rows in one shot, or a producer that accumulates more than 100 entries between flushes. Developers who raised MaxBulkUpdateRows beyond 100 expecting Azure to accept it, or who forgot to chunk their input.","solutions":["Chunk the input into batches of at most MaxBulkUpdateRows before calling, using entries.BatchIEnumerable(100) (the helper the rest of the codebase already uses).","If you genuinely need larger logical batches, keep MaxBulkUpdateRows <= 100 (Azure's hard limit) and loop over chunks rather than raising the cap.","Confirm the configured AzureStoragePolicyOptions.MaxBulkUpdateRows value matches what you chunk against."],"exampleFix":"// before\nawait mgr.BulkInsertTableEntries(allEntries); // throws if > MaxBulkUpdateRows\n\n// after\nforeach (var batch in allEntries.BatchIEnumerable(mgr.StoragePolicyOptions.MaxBulkUpdateRows))\n{\n    await mgr.BulkInsertTableEntries(batch);\n}","handlingStrategy":"validation","validationCode":"var max = mgr.StoragePolicyOptions.MaxBulkUpdateRows;\nif (entries.Count > max)\n    throw new ArgumentOutOfRangeException(nameof(entries), entries.Count, $\"max {max}\");\nawait mgr.BulkInsertTableEntries(entries);","typeGuard":"static bool WithinBulkLimit(IReadOnlyCollection<T> c, int max) => c.Count <= max && c.Count > 0;","tryCatchPattern":null,"preventionTips":["Always chunk with entries.BatchIEnumerable(max)","Never set MaxBulkUpdateRows > 100 (Azure entity-group transaction limit)","Log the actual count alongside the limit when rejecting"],"tags":["argument-validation","azure-storage","batching","config"],"backgroundTag":null,"analyzedSha":"fca799fa70ecb6ad975224271703ca43221f58de","analyzedAt":"2026-08-13T19:55:57.938Z","schemaVersion":2},"datasetVersion":"2026-08-14T00:17:13.853Z"}