{"record":{"id":"1fd96a046c4b4e7d","repo":"pardeike/Harmony","slug":"structfieldrefaccess-typeof-t-typeof-f-for-fieldname-caused","errorCode":null,"errorMessage":"StructFieldRefAccess<{typeof(T)}, {typeof(F)}> for {fieldName} caused an exception","messagePattern":"StructFieldRefAccess<(.+?), (.+?)> for (.+?) caused an exception","errorType":"exception","errorClass":"ArgumentException","httpStatus":null,"severity":"error","filePath":"Harmony/Tools/AccessTools.cs","lineNumber":1539,"sourceCode":"\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=\"fieldName\">The name of the field</param>\r\n\t\t/// <returns>A readable/assignable <see cref=\"StructFieldRef{T,F}\"/> delegate</returns>\r\n\t\t///\r\n\t\tpublic static StructFieldRef<T, F> StructFieldRefAccess<T, F>(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 Tools.StructFieldRefAccess<T, F>(Tools.GetInstanceField(typeof(T), fieldName));\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 {fieldName} caused an exception\", ex);\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\t/// <summary>Creates an instance field reference for a specific instance 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=\"instance\">The instance</param>\r\n\t\t/// <param name=\"fieldName\">The name of the field</param>\r\n\t\t/// <returns>A readable/assignable reference to the field</returns>\r\n\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","sourceCodeStart":1521,"sourceCodeEnd":1557,"githubUrl":"https://github.com/pardeike/Harmony/blob/e7872dc17008bc0ca2b3de1f53fd4120dbd7a17c/Harmony/Tools/AccessTools.cs#L1521-L1557","documentation":"Catch-all wrapper in AccessTools.StructFieldRefAccess<T,F>(fieldName): any exception while resolving the instance field via Tools.GetInstanceField(typeof(T), fieldName) or building the struct ref delegate is rethrown as an ArgumentException naming T, F and fieldName, with the cause as InnerException.","triggerScenarios":"fieldName does not exist on struct T (typically throws NullReferenceException/ArgumentNullException from GetInstanceField), or the field type does not match F.","commonSituations":"Typo'd field name; target library renamed a private field; the field moved to a base class or became auto-property backing field with compiler-generated naming.","solutions":["Verify the field name with AccessTools.Field(typeof(T), fieldName) before calling","Check the target assembly version for renamed fields and update the name","Confirm typeof(F) equals fieldInfo.FieldType","Inspect InnerException to identify whether it was lookup failure vs delegate failure"],"exampleFix":"// before\nvar rf = AccessTools.StructFieldRefAccess<MyStruct, int>(\"_count\"); // field renamed\n// after\nvar fi = AccessTools.Field(typeof(MyStruct), \"_count\") ?? throw new MissingFieldException(nameof(MyStruct), \"_count\");\nvar rf = AccessTools.StructFieldRefAccess<MyStruct, int>(fi);","handlingStrategy":"validation","validationCode":"if (AccessTools.Field(typeof(T), fieldName) is null) throw new MissingFieldException(typeof(T).Name, fieldName);","typeGuard":null,"tryCatchPattern":"try { var rf = AccessTools.StructFieldRefAccess<T, F>(fieldName); }\ncatch (ArgumentException ex) { throw new InvalidOperationException($\"Field '{fieldName}' missing or invalid on {typeof(T)}\", ex.InnerException ?? ex); }","preventionTips":["Resolve and check the FieldInfo before using string-based overloads","Track field names of patched assemblies in tests that run against the real target version","Prefer FieldInfo-based overloads for early, clearer failures"],"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"}