elsa-workflows/elsa-core · warning · ArgumentOutOfRangeException

Status code count must be greater than zero.

Error message

Status code count must be greater than zero.

What it means

The simulate-response session store rotates through a configured list of status codes per session. TryGetNextIndex computes which code comes next and requires statusCodeCount (the size of that list) to be at least 1; a zero or negative count is a programming error, so it throws ArgumentOutOfRangeException naming the parameter.

Solutions

  1. Configure at least one status code for the simulation session before starting it.
  2. Before calling, guard: if (codes == null || codes.Count == 0) handle/return an error instead of calling TryGetNextIndex.
  3. Validate the simulation options at startup (or on session creation) so empty code lists are rejected with a clear message.
  4. If the list is built dynamically, check the filter logic that may be dropping all entries.

Example fix

// before
store.TryGetNextIndex(sessionId, codes.Count, out var idx); // codes is empty
// after
if (codes.Count == 0)
    throw new InvalidOperationException("Simulate response session requires at least one status code.");
store.TryGetNextIndex(sessionId, codes.Count, out var idx);
Defensive patterns

Strategy: validation

Validate before calling

if (statusCodes is null || statusCodes.Count == 0)
    throw new InvalidOperationException("A simulate-response session requires at least one status code.");
store.TryGetNextIndex(sessionId, statusCodes.Count, out var next);

Type guard

static bool HasStatusCodes(System.Collections.Generic.IReadOnlyList<int> codes) => codes is { Count: > 0 };

Try / catch

try
{
    store.TryGetNextIndex(sessionId, count, out var next);
}
catch (ArgumentOutOfRangeException ex) when (ex.ParamName == nameof(count))
{
    logger.LogError("Simulate session '{SessionId}' has no status codes configured.", sessionId);
}

Prevention

When it happens

Trigger: Calling TryGetNextIndex with statusCodeCount <= 0 — typically when the caller built its status-code list from empty configuration, an empty array in options, or a filtering bug that removed all entries.

Common situations: Configuring SimulateResponse with an empty status-codes array and then invoking the simulation endpoint; deserializing configuration where the list was omitted; a code path that computes the count from a filtered/invalid session definition.

Related errors


AI-assisted analysis of elsa-workflows/elsa-core@fe9217bdfa (2026-09-13). Data as JSON: /api/errors/a314c30487f5e694. Report an issue: GitHub.

Appendix: source

Thrown at src/modules/Elsa.Resilience/Endpoints/SimulateResponse/SimulateResponseSessionStore.cs:15

using Elsa.Resilience.Options;
using Microsoft.Extensions.Options;

namespace Elsa.Resilience.Endpoints.SimulateResponse;

public class SimulateResponseSessionStore(IOptions<SimulateResponseOptions> options, TimeProvider timeProvider)
{
    private readonly Dictionary<string, SessionState> _sessions = new(StringComparer.Ordinal);
    private readonly object _lock = new();
    private readonly SimulateResponseOptions _options = options.Value;

    public bool TryGetNextIndex(string sessionId, int statusCodeCount, out int nextIndex)
    {
        if (statusCodeCount <= 0)
            throw new ArgumentOutOfRangeException(nameof(statusCodeCount), "Status code count must be greater than zero.");

        var now = timeProvider.GetUtcNow();
        var expiresAt = now.Add(_options.SessionSlidingExpiration);

        lock (_lock)
        {
            PruneExpired(now);

            nextIndex = _sessions.TryGetValue(sessionId, out var state) ? Math.Min(state.NextIndex, statusCodeCount - 1) : 0;

            if (nextIndex + 1 >= statusCodeCount)
            {
                _sessions.Remove(sessionId);
                return true;
            }

            if (!_sessions.ContainsKey(sessionId) && _sessions.Count >= _options.SessionCapacity)
                return false;

View on GitHub (pinned to fe9217bdfa)