pardeike/Harmony · error · ArgumentException

StructFieldRefAccess<

Error message

StructFieldRefAccess<{typeof(T)}, {typeof(F)}> for {instance}, {fieldName} caused an exception

What it means

Catch-all wrapper in the instance-specific StructFieldRefAccess<T,F>(ref instance, fieldName): any failure resolving the field or creating the ref delegate is rethrown as an ArgumentException naming T, F, the instance and fieldName, with the cause as InnerException.

Solutions

  1. Validate the field exists via AccessTools.Field(typeof(T), fieldName) first
  2. Inspect ex.InnerException for the underlying failure
  3. Match F exactly to the field's FieldType
  4. Switch to the FieldInfo-based overload to fail at lookup time instead of inside the wrapper

Example fix

// before
ref var v = ref AccessTools.StructFieldRefAccess<MyStruct, int>(ref instance, "_count");
// after
var fi = AccessTools.Field(typeof(MyStruct), "_count");
if (fi is null) return;
ref var v = ref AccessTools.StructFieldRefAccess<MyStruct, int>(fi)(ref instance);
Defensive patterns

Strategy: validation

Validate before calling

var fi = AccessTools.Field(typeof(T), fieldName);
if (fi is null || fi.FieldType != typeof(F)) throw new MissingFieldException(typeof(T).Name, fieldName);

Try / catch

try { ref var v = ref AccessTools.StructFieldRefAccess<T, F>(ref instance, fieldName); }
catch (ArgumentException ex) { Log.Error(ex.InnerException ?? ex, "StructFieldRefAccess failed for {Field}", fieldName); }

Prevention

When it happens

Trigger: Same lookup failures as error 86 (missing field name, wrong F) occurring in the overload that takes the struct instance by ref.

Common situations: Struct field renamed in an updated dependency; calling with a struct type that does not actually declare the field; mismatched generic F.

Understand the failure class

Background: 'Could not be found', 'does not exist', 'not found in database': the resource-not-found family when an ID, slug, key, or URI lookup comes back empty — this error's family across 20 libraries.

Related errors


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

Appendix: source

Thrown at Harmony/Tools/AccessTools.cs:1571

		/// <remarks>
		/// <para>
		/// This method is meant for one-off access to a field's value for a single instance.
		/// If you need to access a field's value for potentially multiple instances, use <see cref="StructFieldRefAccess{T, F}(string)"/> instead.
		/// <c>StructFieldRefAccess&lt;T, F&gt;(ref instance, fieldName)</c> is functionally equivalent to <c>StructFieldRefAccess&lt;T, F&gt;(fieldName)(ref instance)</c>.
		/// </para>
		/// </remarks>
		///
		public static ref F StructFieldRefAccess<T, F>(ref T instance, string fieldName) where T : struct
		{
			if (fieldName is null)
				throw new ArgumentNullException(nameof(fieldName));
			try
			{
				return ref Tools.StructFieldRefAccess<T, F>(Tools.GetInstanceField(typeof(T), fieldName))(ref instance);
			}
			catch (Exception ex)
			{
				throw new ArgumentException($"StructFieldRefAccess<{typeof(T)}, {typeof(F)}> for {instance}, {fieldName} caused an exception", ex);
			}
		}

		/// <summary>Creates a field reference delegate for an instance field of a struct</summary>
		/// <typeparam name="T">The struct that defines the instance field</typeparam>
		/// <typeparam name="F">
		/// The type of the field; or if the field's type is a reference type (a class or interface, NOT a struct or other value type),
		/// a type that <see cref="Type.IsAssignableFrom(Type)">is assignable from</see> that type; or if the field's type is an enum type,
		/// either that type or the underlying integral type of that enum type
		/// </typeparam>
		/// <param name="fieldInfo">The field</param>
		/// <returns>A readable/assignable <see cref="StructFieldRef{T,F}"/> delegate</returns>
		/// <remarks>
		/// <para>
		/// This method is meant for cases where the field has already been obtained, avoiding the field searching cost in
		/// e.g. <see cref="StructFieldRefAccess{T, F}(string)"/>.
		/// </para>
		/// </remarks>

View on GitHub (pinned to e7872dc170)