pardeike/Harmony · error · ArgumentException
FieldRefAccess< > for , caused an exception
Error message
FieldRefAccess<{typeof(F)}> for {type}, {fieldName} caused an exception What it means
Wrapping ArgumentException from FieldRefAccess<F>(typeColonName / type, fieldName): thrown when any step fails — field lookup returning null, the struct-instance-field check, or delegate creation. InnerException carries the root cause; the message names the type and field for quick identification.
Solutions
- Inspect ex.InnerException for the actual failure
- Validate with AccessTools.Field(type, fieldName) before building the delegate
- Confirm the field is static or declared on a class
- Log/echo the exact typeColonName string to catch format or rename issues
Example fix
// before
var acc = AccessTools.FieldRefAccess<int>("Game.Enemy:healt"); // typo
// after
var acc = AccessTools.FieldRefAccess<int>("Game.Enemy:health"); Defensive patterns
Strategy: try-catch
Validate before calling
var fi = AccessTools.Field(type, fieldName);
if (fi is null) throw new InvalidOperationException($"Field {fieldName} not found on {type}");
if (fi.IsStatic is false && fi.DeclaringType is Type dt && dt.IsValueType) throw new InvalidOperationException("Struct instance field"); Try / catch
try { var acc = AccessTools.FieldRefAccess<F>(typeColonName); }
catch (ArgumentException ex) { /* inspect ex.InnerException */ } Prevention
- Verify the typeColonName string against the target assembly each version bump
- Resolve the FieldInfo first, then build the delegate
- Log the exact string on failure for fast diagnosis
When it happens
Trigger: Calling AccessTools.FieldRefAccess<F>("Namespace.Type:fieldName") or FieldRefAccess<F>(type, fieldName) where the field does not exist, is an instance field of a struct, or cannot support a ref-returning delegate.
Common situations: Typo in TypeFullName:MemberName string after an assembly update; attempting struct instance field refs; obfuscated field names in shipped game assemblies.
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
- FieldRefAccess< , > for caused an exception
- FieldRefAccess< , > for , caused an exception
- T (FieldRefAccess instance type) must not be a value type
- Either FieldDeclaringType must be a class or field must be…
- FieldRefAccess< , > for caused an exception
AI-assisted analysis of pardeike/Harmony@e7872dc170 (2026-09-15).
Data as JSON: /api/errors/d2d0ecacde049ddf.
Report an issue: GitHub.
Appendix: source
Thrown at Harmony/Tools/AccessTools.cs:1381
try
{
var fieldInfo = Field(type, fieldName);
if (fieldInfo is null)
throw new MissingFieldException(type.Name, fieldName);
// Backwards compatibility: This supports static fields, even those defined in structs. For static fields, T is effectively ignored.
if (fieldInfo.IsStatic is false && fieldInfo.DeclaringType is Type declaringType)
{
// When fieldInfo is passed to FieldRefAccess methods, the T generic class constraint is insufficient to ensure that
// the field is not a struct instance field, since T could be object, ValueType, or an interface that the struct implements.
if (declaringType.IsValueType)
throw new ArgumentException("Either FieldDeclaringType must be a class or field must be static");
}
// Field's declaring type cannot be object, since object has no fields, so always need a castclass for T=object.
return Tools.FieldRefAccess<object, F>(fieldInfo, needCastclass: true);
}
catch (Exception ex)
{
throw new ArgumentException($"FieldRefAccess<{typeof(F)}> for {type}, {fieldName} caused an exception", ex);
}
}
/// <summary>Creates a field reference delegate for an instance field of a class or static field (NOT an instance field of a struct)</summary>
/// <typeparam name="F"> type of the field</typeparam>
/// <param name="typeColonName">The member in the form <c>TypeFullName:MemberName</c>, where TypeFullName matches the form recognized by <a href="https://docs.microsoft.com/en-us/dotnet/api/system.type.gettype">Type.GetType</a> like <c>Some.Namespace.Type</c>.</param>
/// <returns>A readable/assignable <see cref="FieldRef{T,F}"/> delegate with <c>T=object</c></returns>
///
public static FieldRef<object, F> FieldRefAccess<F>(string typeColonName)
{
var info = Tools.TypColonName(typeColonName);
return FieldRefAccess<F>(info.type, info.name);
}
/// <summary>Creates a field reference delegate for an instance field of a class or static field (NOT an instance field of a struct)</summary>
/// <typeparam name="T">
/// An arbitrary type if the field is static; otherwise the class that defines the field, or a parent class (including <see cref="object"/>),
/// implemented interface, or derived class of this type ("<c>instanceOfT is FieldDeclaringType</c>" must be possible)
View on GitHub (pinned to e7872dc170)