jstedfast/MailKit · error · ArgumentOutOfRangeException

index

Error message

index

What it means

The BodyPartCollection this[int index] indexer throws ArgumentOutOfRangeException when index is negative or >= collection.Count. MailKit's indexer performs explicit bounds checks and reports the offending parameter as 'index'.

Solutions

  1. Check Count before indexing: for (int i = 0; i < bodyParts.Count; i++) ...
  2. Verify the message actually has body parts (guard against empty collections) before [0].
  3. Enumerate with foreach (BodyPart part in bodyParts) to eliminate index arithmetic.

Example fix

// before
for (int i = 0; i <= bodyParts.Count; i++)
    Process(bodyParts[i]);
// after
for (int i = 0; i < bodyParts.Count; i++)
    Process(bodyParts[i]);
Defensive patterns

Strategy: validation

Validate before calling

bool inRange = index >= 0 && index < bodyParts.Count;

Type guard

bool TryGetPart(BodyPartCollection parts, int index, out BodyPart value) { value = null; if (index < 0 || index >= parts.Count) return false; value = parts[index]; return true; }

Try / catch

try { part = bodyParts[index]; } catch (ArgumentOutOfRangeException) { part = null; }

Prevention

When it happens

Trigger: Accessing bodyParts[i] where i < 0 or i >= bodyParts.Count, e.g. looping with <= instead of <, or assuming a non-empty collection without checking Count.

Common situations: Loop bounds off-by-one when walking multipart children; assuming a message has at least one body part; stale code after server responses changed so a part is missing; counting nested parts with the wrong Count source.

Related errors


AI-assisted analysis of jstedfast/MailKit@9d3859a785 (2026-09-15). Data as JSON: /api/errors/d2898d84cce36aba. Report an issue: GitHub.

Appendix: source

Thrown at MailKit/BodyPartCollection.cs:184

			return collection.Remove (part);
		}

		/// <summary>
		/// Get the body part at the specified index.
		/// </summary>
		/// <remarks>
		/// Gets the body part at the specified index.
		/// </remarks>
		/// <value>The body part at the specified index.</value>
		/// <param name="index">The index.</param>
		/// <exception cref="System.ArgumentOutOfRangeException">
		/// <paramref name="index"/> is out of range.
		/// </exception>
		public BodyPart this [int index] {
			get {
				if (index < 0 || index >= collection.Count)
					throw new ArgumentOutOfRangeException (nameof (index));

				return collection[index];
			}
		}

		/// <summary>
		/// Gets the index of the body part matching the specified URI.
		/// </summary>
		/// <remarks>
		/// <para>Finds the index of the body part matching the specified URI, if it exists.</para>
		/// <para>If the URI scheme is <c>"cid"</c>, then matching is performed based on the Content-Id header
		/// values, otherwise the Content-Location headers are used. If the provided URI is absolute and a child
		/// part's Content-Location is relative, then then the child part's Content-Location URI will be combined
		/// with the value of its Content-Base header, if available, otherwise it will be combined with the
		/// multipart/related part's Content-Base header in order to produce an absolute URI that can be
		/// compared with the provided absolute URI.</para>
		/// </remarks>
		/// <returns>The index of the part matching the specified URI if found; otherwise <c>-1</c>.</returns>

View on GitHub (pinned to 9d3859a785)