{"record":{"id":"16fcf0ddf65a713a","repo":"pardeike/Harmony","slug":"structfieldrefaccess-typeof-t-typeof-f-for-instance","errorCode":null,"errorMessage":"StructFieldRefAccess<{typeof(T)}, {typeof(F)}> for {instance}, {fieldName} caused an exception","messagePattern":"StructFieldRefAccess<(.+?), (.+?)> for (.+?), (.+?) caused an exception","errorType":"exception","errorClass":"ArgumentException","httpStatus":null,"severity":"error","filePath":"Harmony/Tools/AccessTools.cs","lineNumber":1571,"sourceCode":"\t\t/// <remarks>\r\n\t\t/// <para>\r\n\t\t/// This method is meant for one-off access to a field's value for a single instance.\r\n\t\t/// If you need to access a field's value for potentially multiple instances, use <see cref=\"StructFieldRefAccess{T, F}(string)\"/> instead.\r\n\t\t/// <c>StructFieldRefAccess&lt;T, F&gt;(ref instance, fieldName)</c> is functionally equivalent to <c>StructFieldRefAccess&lt;T, F&gt;(fieldName)(ref instance)</c>.\r\n\t\t/// </para>\r\n\t\t/// </remarks>\r\n\t\t///\r\n\t\tpublic static ref F StructFieldRefAccess<T, F>(ref T instance, string fieldName) where T : struct\r\n\t\t{\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\treturn ref Tools.StructFieldRefAccess<T, F>(Tools.GetInstanceField(typeof(T), fieldName))(ref 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($\"StructFieldRefAccess<{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 struct</summary>\r\n\t\t/// <typeparam name=\"T\">The struct that defines the instance field</typeparam>\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=\"fieldInfo\">The field</param>\r\n\t\t/// <returns>A readable/assignable <see cref=\"StructFieldRef{T,F}\"/> delegate</returns>\r\n\t\t/// <remarks>\r\n\t\t/// <para>\r\n\t\t/// This method is meant for cases where the field has already been obtained, avoiding the field searching cost in\r\n\t\t/// e.g. <see cref=\"StructFieldRefAccess{T, F}(string)\"/>.\r\n\t\t/// </para>\r\n\t\t/// </remarks>\r","sourceCodeStart":1553,"sourceCodeEnd":1589,"githubUrl":"https://github.com/pardeike/Harmony/blob/e7872dc17008bc0ca2b3de1f53fd4120dbd7a17c/Harmony/Tools/AccessTools.cs#L1553-L1589","documentation":"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.","triggerScenarios":"Same lookup failures as error 86 (missing field name, wrong F) occurring in the overload that takes the struct instance by ref.","commonSituations":"Struct field renamed in an updated dependency; calling with a struct type that does not actually declare the field; mismatched generic F.","solutions":["Validate the field exists via AccessTools.Field(typeof(T), fieldName) first","Inspect ex.InnerException for the underlying failure","Match F exactly to the field's FieldType","Switch to the FieldInfo-based overload to fail at lookup time instead of inside the wrapper"],"exampleFix":"// before\nref var v = ref AccessTools.StructFieldRefAccess<MyStruct, int>(ref instance, \"_count\");\n// after\nvar fi = AccessTools.Field(typeof(MyStruct), \"_count\");\nif (fi is null) return;\nref var v = ref AccessTools.StructFieldRefAccess<MyStruct, int>(fi)(ref instance);","handlingStrategy":"validation","validationCode":"var fi = AccessTools.Field(typeof(T), fieldName);\nif (fi is null || fi.FieldType != typeof(F)) throw new MissingFieldException(typeof(T).Name, fieldName);","typeGuard":null,"tryCatchPattern":"try { ref var v = ref AccessTools.StructFieldRefAccess<T, F>(ref instance, fieldName); }\ncatch (ArgumentException ex) { Log.Error(ex.InnerException ?? ex, \"StructFieldRefAccess failed for {Field}\", fieldName); }","preventionTips":["Match F exactly to the field type","Use FieldInfo lookups once at startup, fail fast there","Re-verify field names after every target-library update"],"tags":["harmony","reflection","struct","fieldref"],"backgroundTag":"resource-not-found","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"}