pardeike/Harmony · error · ArgumentException

cannot contain zeros

Error message

{nameof(positions)} cannot contain zeros

What it means

InnerMethod wraps a MethodInfo together with parameter positions that should be treated specially (e.g. skipped or rewritten). Harmony rejects a positions array containing 0 because positions are 1-based argument indexes; 0 is meaningless and would corrupt argument handling downstream.

Solutions

  1. Use 1-based argument positions (first argument is 1, instance 'this' context is handled separately)
  2. Filter out zeros before constructing: positions = positions.Where(p => p != 0).ToArray()
  3. Double-check the loop or mapping that generates the indexes for an off-by-one

Example fix

// before
new InnerMethod(method, 0, 2);
// after
new InnerMethod(method, 1, 2);
Defensive patterns

Strategy: validation

Validate before calling

if (positions.Contains(0)) throw new ArgumentException("positions must be 1-based and non-zero");

Prevention

When it happens

Trigger: Calling the InnerMethod(MethodInfo, params int[]) constructor with any element of the positions array equal to 0, typically from computed/loop-derived indexes with an off-by-one.

Common situations: Transpilers or patch tools building argument-redirect helpers that start counting at 0 instead of 1; arrays built from zero-initialized buffers; passing raw loop counters.

Understand the failure class

Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.

Related errors


AI-assisted analysis of pardeike/Harmony@e7872dc170 (2026-09-15). Data as JSON: /api/errors/99acb8e4f6839287. Report an issue: GitHub.

Appendix: source

Thrown at Harmony/Public/InnerMethod.cs:37

		[NonSerialized]
		private MethodInfo method;
		private int methodToken;
		private string moduleGUID;

		/// <summary>Which occcurances (1-based) of the method, negative numbers are counting from the end, empty array means all occurances</summary>
		///
		public int[] positions;

		/// <summary>Creates an InnerMethod</summary>
		/// <param name="method">The inner method</param>
		/// <param name="positions">Which occcurances (1-based) of the method, negative numbers are counting from the end, empty array means all occurances</param>
		///
		public InnerMethod(MethodInfo method, params int[] positions)
		{
			if (method == null)
				throw new ArgumentNullException(nameof(method));
			if (positions.Any(p => p == 0))
				throw new ArgumentException($"{nameof(positions)} cannot contain zeros");

			Method = method;
			this.positions = positions;
		}

		internal InnerMethod(int methodToken, string moduleGUID, int[] positions)
		{
			this.methodToken = methodToken;
			this.moduleGUID = moduleGUID;
			this.positions = positions;
		}

		/// <summary>The inner method</summary>
		///
#if NET5_0_OR_GREATER
		[JsonIgnore]
#endif
		public MethodInfo Method

View on GitHub (pinned to e7872dc170)