{"record":{"id":"3fcc9ade70a731eb","repo":"pardeike/Harmony","slug":"fieldrefaccess-typeof-t-typeof-f-for-instance-fieldname","errorCode":null,"errorMessage":"FieldRefAccess<{typeof(T)}, {typeof(F)}> for {instance}, {fieldName} caused an exception","messagePattern":"FieldRefAccess<(.+?), (.+?)> for (.+?), (.+?) caused an exception","errorType":"exception","errorClass":"ArgumentException","httpStatus":null,"severity":"error","filePath":"Harmony/Tools/AccessTools.cs","lineNumber":1328,"sourceCode":"\t\t/// </para>\r\n\t\t/// </remarks>\r\n\t\t///\r\n\t\tpublic static ref F FieldRefAccess<T, F>(T instance, string fieldName)\r\n\t\t{\r\n\t\t\tif (instance is null)\r\n\t\t\t\tthrow new ArgumentNullException(nameof(instance));\r\n\t\t\tif (fieldName is null)\r\n\t\t\t\tthrow new ArgumentNullException(nameof(fieldName));\r\n\t\t\ttry\r\n\t\t\t{\r\n\t\t\t\tvar delegateInstanceType = typeof(T);\r\n\t\t\t\tif (delegateInstanceType.IsValueType)\r\n\t\t\t\t\tthrow new ArgumentException(\"T (FieldRefAccess instance type) must not be a value type\");\r\n\t\t\t\treturn ref Tools.FieldRefAccess<T, F>(Tools.GetInstanceField(delegateInstanceType, fieldName), needCastclass: false)(instance);\r\n\t\t\t}\r\n\t\t\tcatch (Exception ex)\r\n\t\t\t{\r\n\t\t\t\tthrow new ArgumentException($\"FieldRefAccess<{typeof(T)}, {typeof(F)}> for {instance}, {fieldName} caused an exception\", ex);\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\t/// <summary>Creates a field reference delegate for an instance field of a class or static field (NOT an instance field of a struct)</summary>\r\n\t\t/// <typeparam name=\"F\">\r\n\t\t/// 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),\r\n\t\t/// a type that <see cref=\"Type.IsAssignableFrom(Type)\">is assignable from</see> that type; or if the field's type is an enum type,\r\n\t\t/// either that type or the underlying integral type of that enum type\r\n\t\t/// </typeparam>\r\n\t\t/// <param name=\"type\">\r\n\t\t/// The type that defines the field, or derived class of this type; must not be a struct type unless the field is static\r\n\t\t/// </param>\r\n\t\t/// <param name=\"fieldName\">The name of the field</param>\r\n\t\t/// <returns>\r\n\t\t/// A readable/assignable <see cref=\"FieldRef{T,F}\"/> delegate with <c>T=object</c>\r\n\t\t/// (for static fields, the <c>instance</c> delegate parameter is ignored)\r\n\t\t/// </returns>\r\n\t\t/// <remarks>\r","sourceCodeStart":1310,"sourceCodeEnd":1346,"githubUrl":"https://github.com/pardeike/Harmony/blob/e7872dc17008bc0ca2b3de1f53fd4120dbd7a17c/Harmony/Tools/AccessTools.cs#L1310-L1346","documentation":"Wrapping ArgumentException thrown by FieldRefAccess<T,F>(fieldName) when any inner operation fails (value-type T, field not found, type mismatch, delegate creation failure). The original exception is the InnerException and the message includes the instance and field name for diagnosis.","triggerScenarios":"Calling AccessTools.FieldRefAccess<T, F>(fieldName) with T a struct, a fieldName that does not resolve to an instance field of type F, or when delegate construction throws.","commonSituations":"Field renamed in a target-assembly update; F declared as int while field is float; struct instance type used by mistake.","solutions":["Check ex.InnerException for the root cause","Confirm the field exists with the exact type: AccessTools.Field(typeof(T), fieldName)?.FieldType == typeof(F)","Ensure T is a reference type; use StaticFieldRefAccess for static fields"],"exampleFix":"// before\nvar acc = AccessTools.FieldRefAccess<Player, float>(\"hp\"); // hp is actually int\n// after\nvar acc = AccessTools.FieldRefAccess<Player, int>(\"hp\");","handlingStrategy":"try-catch","validationCode":"if (typeof(T).IsValueType) throw new InvalidOperationException(\"T must be a class\");\nvar fi = AccessTools.Field(typeof(T), fieldName);\nif (fi?.FieldType != typeof(F)) throw new InvalidOperationException(\"Field missing or type mismatch\");","typeGuard":null,"tryCatchPattern":"try { var acc = AccessTools.FieldRefAccess<T, F>(fieldName); }\ncatch (ArgumentException ex) { /* inspect ex.InnerException */ }","preventionTips":["Validate the FieldInfo before creating the delegate","Keep field names in one constants class to survive renames","Test ref-delegate creation at patch initialization, not lazily"],"tags":["reflection","harmony","fieldref","wrapping-exception"],"backgroundTag":"invalid-argument-value","analyzedSha":"e7872dc17008bc0ca2b3de1f53fd4120dbd7a17c","analyzedAt":"2026-09-15T22:47:11.550Z","contentChangedAt":"2026-09-15T22:47:11.550Z","schemaVersion":2},"datasetVersion":"2026-09-16T09:17:16.951Z"}