restsharp/RestSharp · error · ArgumentOutOfRangeException

value must be non-negative

Error message

value must be non-negative

What it means

Thrown by the Index polyfill constructor on older target frameworks (netstandard2.0, net471, net48) where System.Index is not built-in. The Index struct backs the C# range/index syntax (e.g. array[^1]). The constructor rejects negative values because an index position cannot be negative. It mirrors the contract of the official .NET runtime Index type.

Source

Thrown at src/RestSharp/Polyfills/Index.cs:31

/// Index is used by the C# compiler to support the new index syntax
/// <code>
/// int[] someArray = new int[5] { 1, 2, 3, 4, 5 } ;
/// int lastElement = someArray[^1]; // lastElement = 5
/// </code>
/// </remarks>
readonly struct Index : IEquatable<Index> {
    readonly int _value;

    /// <summary>Construct an Index using a value and indicating if the index is from the start or from the end.</summary>
    /// <param name="value">The index value. it has to be zero or positive number.</param>
    /// <param name="fromEnd">Indicating if the index is from the start or from the end.</param>
    /// <remarks>
    /// If the Index constructed from the end, index value 1 means pointing at the last element and index value 0 means pointing at beyond last element.
    /// </remarks>
    [MethodImpl(MethodImplOptions.AggressiveInlining)]
    public Index(int value, bool fromEnd = false) {
        if (value < 0) {
            throw new ArgumentOutOfRangeException(nameof(value), "value must be non-negative");
        }

        if (fromEnd)
            _value = ~value;
        else
            _value = value;
    }

    // The following private constructors mainly created for perf reason to avoid the checks
    Index(int value) => _value = value;

    /// <summary>Create an Index pointing at first element.</summary>
    public static Index Start => new(0);

    /// <summary>Create an Index pointing at beyond last element.</summary>
    public static Index End => new(~0);

    /// <summary>Create an Index from the start at the position indicated by the value.</summary>

View on GitHub (pinned to 6a50821692)

Solutions

  1. Upgrade the consuming project to a modern TFM (net8.0/net9.0) so the built-in System.Index is used and this polyfill is not compiled.
  2. Ensure any inputs that feed into string slicing (BaseUrl, Resource, ContentType values) are non-empty before they reach RestSharp's URI/content assembly code.
  3. If reproducing directly, verify the value passed to new Index is >= 0 before construction.

Example fix

// before
var ch = baseUrl.AbsoluteUri[^1]; // AbsoluteUri empty -> negative index path

// after
if (!string.IsNullOrEmpty(baseUrl.AbsoluteUri)) {
    var ch = baseUrl.AbsoluteUri[^1];
}
Defensive patterns

Strategy: validation

Validate before calling

// Validate before any index/range operation that could go negative on legacy TFMs
int value = ComputeIndex();
if (value < 0) throw new ArgumentOutOfRangeException(nameof(value), "Index must be non-negative");
var index = new Index(value);

Prevention

When it happens

Trigger: Calling new Index(value, fromEnd) or implicitly converting an int to Index where the int is negative. In RestSharp internals this is reached when compiled index/range expressions (like assembled[1..] or AbsoluteUri[^1]) resolve to a negative computed position. Direct construction with a negative value also triggers it.

Common situations: Running RestSharp on netstandard2.0/net4x where the polyfill is active, combined with an edge-case string/URI that is empty or has unexpected length, so a computed index like str[^1] effectively resolves through a negative intermediate. Rare for end users; mostly a library-internal invariant guard.

Related errors


AI-assisted analysis of restsharp/RestSharp@6a50821692 (2026-08-13). Data as JSON: /api/errors/bbf22a2549539805. Report an issue: GitHub.