{"record":{"id":"ebdd169cdd16493c","repo":"elsa-workflows/elsa-core","slug":"capacity-must-be-greater-than-zero-ringbuffer","errorCode":null,"errorMessage":"Capacity must be greater than zero.","messagePattern":"Capacity must be greater than zero\\.","errorType":"validation","errorClass":"ArgumentOutOfRangeException","httpStatus":null,"severity":"error","filePath":"src/modules/Elsa.Diagnostics.StructuredLogs/Providers/InMemory/RingBuffer.cs","lineNumber":12,"sourceCode":"namespace Elsa.Diagnostics.StructuredLogs.Providers.InMemory;\n\npublic class RingBuffer<T>\n{\n    private readonly Queue<T> _items = new();\n    private readonly object _lock = new();\n    private readonly int _capacity;\n    \n    public RingBuffer(int capacity)\n    {\n        if (capacity <= 0)\n            throw new ArgumentOutOfRangeException(nameof(capacity), \"Capacity must be greater than zero.\");\n        \n        _capacity = capacity;\n    }\n    \n    public long DroppedCount { get; private set; }\n    \n    public void Add(T item)\n    {\n        lock (_lock)\n        {\n            if (_items.Count == _capacity)\n            {\n                _items.Dequeue();\n                DroppedCount++;\n            }\n            \n            _items.Enqueue(item);\n        }","sourceCodeStart":1,"sourceCodeEnd":30,"githubUrl":"https://github.com/elsa-workflows/elsa-core/blob/fe9217bdfa0e27f0e09e45006eb6898f616e513d/src/modules/Elsa.Diagnostics.StructuredLogs/Providers/InMemory/RingBuffer.cs#L1-L30","documentation":"The InMemory structured-log RingBuffer constructor validates that capacity is strictly greater than zero and throws ArgumentOutOfRangeException otherwise. A ring buffer with no capacity cannot hold any entries, so the library rejects it eagerly rather than silently dropping all logs.","triggerScenarios":"Constructing new RingBuffer(0) or new RingBuffer(negative), typically when capacity comes from configuration (e.g. structured log options) that is unset, zero, or parsed incorrectly.","commonSituations":"An appsettings value like StructuredLogs:Capacity left at 0, a config binder defaulting a missing int to 0, or passing a computed capacity that underflows.","solutions":["Pass a positive capacity, e.g. new RingBuffer(1000).","If capacity comes from options, validate/default it: capacity = options.Capacity > 0 ? options.Capacity : 1000.","Fix the configuration source so the bound value is a positive integer."],"exampleFix":"// before\nvar buffer = new RingBuffer(options.Capacity);\n// after\nvar capacity = options.Capacity > 0 ? options.Capacity : 1000;\nvar buffer = new RingBuffer(capacity);","handlingStrategy":"validation","validationCode":"if (capacity <= 0) throw new Error('RingBuffer capacity must be greater than zero; got ' + capacity); const buffer = new RingBuffer(capacity);","typeGuard":"function isValidCapacity(v) { return typeof v === 'number' && Number.isInteger(v) && v > 0; }","tryCatchPattern":"try { buffer = new RingBuffer(options.Capacity); } catch (ArgumentOutOfRangeException ex) { buffer = new RingBuffer(DefaultCapacity); logger.LogWarning(ex, 'Falling back to default log capacity'); }","preventionTips":["Default capacity from configuration with a positive fallback value.","Validate options classes on bind (IValidateOptions / DataAnnotations range checks).","Never pass raw config ints to constructors without a positivity check.","Document required capacity settings for operators."],"tags":["configuration","argument-out-of-range","logging"],"backgroundTag":"argument-out-of-range","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"}