{"record":{"id":"ca5e3aae7113f2ae","repo":"pardeike/Harmony","slug":"staticfieldrefaccess-typeof-f-for-type-fieldname-caused-an","errorCode":null,"errorMessage":"StaticFieldRefAccess<{typeof(F)}> for {type}, {fieldName} caused an exception","messagePattern":"StaticFieldRefAccess<(.+?)> for (.+?), (.+?) caused an exception","errorType":"exception","errorClass":"ArgumentException","httpStatus":null,"severity":"error","filePath":"Harmony/Tools/AccessTools.cs","lineNumber":1682,"sourceCode":"\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\">The type (can be class or struct) the field is defined in</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///\r\n\t\tpublic static ref F StaticFieldRefAccess<F>(Type type, string fieldName)\r\n\t\t{\r\n\t\t\ttry\r\n\t\t\t{\r\n\t\t\t\tvar fieldInfo = Field(type, fieldName);\r\n\t\t\t\tif (fieldInfo is null)\r\n\t\t\t\t\tthrow new MissingFieldException(type.Name, fieldName);\r\n\t\t\t\treturn ref Tools.StaticFieldRefAccess<F>(fieldInfo)();\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($\"StaticFieldRefAccess<{typeof(F)}> for {type}, {fieldName} caused an exception\", ex);\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\t/// <summary>Creates a static field reference</summary>\r\n\t\t/// <typeparam name=\"F\">The type of the field</typeparam>\r\n\t\t/// <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>\r\n\t\t/// <returns>A readable/assignable reference to the field</returns>\r\n\t\t///\r\n\t\tpublic static ref F StaticFieldRefAccess<F>(string typeColonName)\r\n\t\t{\r\n\t\t\tvar info = Tools.TypColonName(typeColonName);\r\n\t\t\treturn ref StaticFieldRefAccess<F>(info.type, info.name);\r\n\t\t}\r\n\r\n\t\t/// <summary>Creates a static field reference</summary>\r\n\t\t/// <typeparam name=\"T\">An arbitrary type (by convention, the type the field is defined in)</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","sourceCodeStart":1664,"sourceCodeEnd":1700,"githubUrl":"https://github.com/pardeike/Harmony/blob/e7872dc17008bc0ca2b3de1f53fd4120dbd7a17c/Harmony/Tools/AccessTools.cs#L1664-L1700","documentation":"AccessTools.StaticFieldRefAccess<F>(type, fieldName) wraps any failure while resolving or accessing the named static field in an ArgumentException, preserving the original exception as InnerException. Harmony throws it because the requested static field could not be resolved (MissingFieldException) or its ref-returning accessor could not be invoked.","triggerScenarios":"Calling AccessTools.StaticFieldRefAccess<F>(type, fieldName) where type has no field named fieldName (inner MissingFieldException), or Tools.StaticFieldRefAccess<F>(fieldInfo)() fails when invoking the generated accessor, e.g. the field type does not match F.","commonSituations":"Typo in the field name, field renamed in a game/library update, wrong type parameter F vs the actual static field type, or targeting a field that is instance instead of static.","solutions":["Check the inner exception (ex.InnerException) to see whether it is MissingFieldException (name/type wrong) or something else.","Verify the field exists and is static: AccessTools.Field(type, fieldName) != null and fieldInfo.IsStatic.","Ensure the generic type F exactly matches the field's declared type.","Use AccessTools.StaticFieldRefAccess<T, F>(\"FieldName\") with the correct declaring type T."],"exampleFix":"// before\nvar refAccess = AccessTools.StaticFieldRefAccess<int>(typeof(GameState), \"sccore\");\n// after\nvar refAccess = AccessTools.StaticFieldRefAccess<int>(typeof(GameState), \"score\");","handlingStrategy":"try-catch","validationCode":"var fi = AccessTools.Field(type, fieldName);\nif (fi is null || !fi.IsStatic || fi.FieldType != typeof(F))\n    throw new InvalidOperationException($\"{type.Name}.{fieldName} is not a static {typeof(F)} field\");","typeGuard":"bool IsValidStaticField<F>(Type type, string name) => AccessTools.Field(type, name) is { IsStatic: true } fi && fi.FieldType == typeof(F);","tryCatchPattern":"try { var r = AccessTools.StaticFieldRefAccess<F>(type, fieldName); }\ncatch (ArgumentException ex) when (ex.InnerException is MissingFieldException) { /* wrong type/name */ }\ncatch (ArgumentException ex) { /* type mismatch - log ex.InnerException */ }","preventionTips":["Always pre-resolve with AccessTools.Field and null-check before taking ref access.","Assert fieldInfo.IsStatic and FieldType == typeof(F).","Pin/re-verify member names after every target library update."],"tags":["reflection","static-field","harmony"],"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"}