pardeike/Harmony · error · ArgumentException
StaticFieldRefAccess<
Error message
StaticFieldRefAccess<{typeof(F)}> for {fieldInfo} caused an exception What it means
AccessTools.StaticFieldRefAccess<F>(fieldInfo) wraps any exception from creating the delegate-returning ref accessor in an ArgumentException. This overload returns the accessor delegate itself, so failures here mean the FieldInfo could not be compiled into a ref getter.
Solutions
- Check InnerException for the actual failure.
- Verify fieldInfo is non-null and IsStatic.
- Ensure F equals fieldInfo.FieldType.
- Resolve the FieldInfo via AccessTools.Field on the correct declaring type.
Example fix
// before var getter = AccessTools.StaticFieldRefAccess<float>(instanceFieldInfo); // after var fi = AccessTools.Field(typeof(Physics), "gravity"); var getter = AccessTools.StaticFieldRefAccess<float>(fi); // gravity is static float
Defensive patterns
Strategy: validation
Validate before calling
if (fieldInfo is null || !fieldInfo.IsStatic || fieldInfo.FieldType != typeof(F))
return null; // skip creating accessor
var getter = AccessTools.StaticFieldRefAccess<F>(fieldInfo); Type guard
bool CanMakeRefAccessor<F>(FieldInfo fi) => fi is { IsStatic: true } && fi.FieldType == typeof(F); Try / catch
try { var getter = AccessTools.StaticFieldRefAccess<F>(fieldInfo); }
catch (ArgumentException ex) { logger.Warn(ex.InnerException, "cannot build accessor for {0}", fieldInfo); } Prevention
- Do not confuse the delegate-returning overload with the ref-returning overload.
- Check IsStatic/FieldType before use.
- Re-resolve FieldInfo on the declaring type after target updates.
When it happens
Trigger: Calling AccessTools.StaticFieldRefAccess<F>(fieldInfo) with a non-static FieldInfo, a FieldInfo whose type differs from F, or an otherwise unusable FieldInfo (e.g. from a dynamic/collected type).
Common situations: Mixing up the delegate-returning overload with the ref-returning one, passing null or a FieldInfo resolved from a different declaring type, F not matching after a target update.
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
- Field must not be static
- StaticFieldRefAccess<
- StaticFieldRefAccess<
- The type must declare an empty constructor (the constructor…
- Value cannot be null. (Parameter 'fromMethod')
AI-assisted analysis of pardeike/Harmony@e7872dc170 (2026-09-15).
Data as JSON: /api/errors/046b4e382f6f6288.
Report an issue: GitHub.
Appendix: source
Thrown at Harmony/Tools/AccessTools.cs:1744
/// <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="FieldRef{F}"/> delegate</returns>
///
public static FieldRef<F> StaticFieldRefAccess<F>(FieldInfo fieldInfo)
{
if (fieldInfo is null)
throw new ArgumentNullException(nameof(fieldInfo));
try
{
return Tools.StaticFieldRefAccess<F>(fieldInfo);
}
catch (Exception ex)
{
throw new ArgumentException($"StaticFieldRefAccess<{typeof(F)}> for {fieldInfo} caused an exception", ex);
}
}
#pragma warning disable CS1591
[Obsolete("This overload only exists for runtime backwards compatibility and will be removed in Harmony 3. Use MethodDelegate(MethodInfo, object, bool, Type[]) instead")]
[EditorBrowsable(EditorBrowsableState.Never)]
public static DelegateType MethodDelegate<DelegateType>(MethodInfo method, object instance, bool virtualCall) where DelegateType : Delegate
=> MethodDelegate<DelegateType>(method, instance, virtualCall, null);
#pragma warning restore CS1591
/// <summary>Creates a delegate to a given method</summary>
/// <typeparam name="DelegateType">The delegate Type</typeparam>
/// <param name="method">The method to create a delegate from.</param>
/// <param name="instance">
/// Only applies for instance methods. If <c>null</c> (default), returned delegate is an open (a.k.a. unbound) instance delegate
/// where an instance is supplied as the first argument to the delegate invocation; else, delegate is a closed (a.k.a. bound)
/// instance delegate where the delegate invocation always applies to the given <paramref name="instance"/>.
/// </param>
View on GitHub (pinned to e7872dc170)