{"record":{"id":"c30fd0fb183ab685","repo":"pardeike/Harmony","slug":"field-must-not-be-static-tools","errorCode":null,"errorMessage":"Field must not be static","messagePattern":"Field must not be static","errorType":"exception","errorClass":"ArgumentException","httpStatus":null,"severity":"error","filePath":"Harmony/Tools/Tools.cs","lineNumber":123,"sourceCode":"\t\t\tValidateFieldType<F>(fieldInfo);\r\n\r\n\t\t\tvar dm = new DynamicMethodDefinition($\"__refget_{fieldInfo.DeclaringType?.Name ?? \"null\"}_static_fi_{fieldInfo.Name}\",\r\n\t\t\t\ttypeof(F).MakeByRefType(), []);\r\n\r\n\t\t\tvar il = dm.GetILGenerator();\r\n\t\t\til.Emit(OpCodes.Ldsflda, fieldInfo);\r\n\t\t\til.Emit(OpCodes.Ret);\r\n\r\n\t\t\treturn dm.Generate().CreateDelegate<FieldRef<F>>();\r\n\t\t}\r\n\r\n\t\tinternal static FieldInfo GetInstanceField(Type type, string fieldName)\r\n\t\t{\r\n\t\t\tvar fieldInfo = Field(type, fieldName);\r\n\t\t\tif (fieldInfo is null)\r\n\t\t\t\tthrow new MissingFieldException(type.Name, fieldName);\r\n\t\t\tif (fieldInfo.IsStatic)\r\n\t\t\t\tthrow new ArgumentException(\"Field must not be static\");\r\n\t\t\treturn fieldInfo;\r\n\t\t}\r\n\r\n\t\tinternal static bool FieldRefNeedsClasscast(Type delegateInstanceType, Type declaringType)\r\n\t\t{\r\n\t\t\tvar needCastclass = false;\r\n\t\t\tif (delegateInstanceType != declaringType)\r\n\t\t\t{\r\n\t\t\t\tneedCastclass = delegateInstanceType.IsAssignableFrom(declaringType);\r\n\t\t\t\tif (needCastclass is false && declaringType.IsAssignableFrom(delegateInstanceType) is false)\r\n\t\t\t\t\tthrow new ArgumentException(\"FieldDeclaringType must be assignable from or to T (FieldRefAccess instance type) - \" +\r\n\t\t\t\t\t\t\"\\\"instanceOfT is FieldDeclaringType\\\" must be possible\");\r\n\t\t\t}\r\n\t\t\treturn needCastclass;\r\n\t\t}\r\n\r\n\t\tinternal static void ValidateStructField<T, F>(FieldInfo fieldInfo) where T : struct\r\n\t\t{\r","sourceCodeStart":105,"sourceCodeEnd":141,"githubUrl":"https://github.com/pardeike/Harmony/blob/e7872dc17008bc0ca2b3de1f53fd4120dbd7a17c/Harmony/Tools/Tools.cs#L105-L141","documentation":"Harmony's Tools.GetInstanceField resolves a field by name and refuses to return static fields because the caller asked for an instance field via reflection on a specific instance type. Static fields live on the type, not the instance, so returning one here would be a caller bug or a wrong fieldName/type pair.","triggerScenarios":"Calling Tools.GetInstanceField(type, fieldName) (directly or via AccessTools/field-ref helpers) where fieldName names a static field on the given type instead of an instance field.","commonSituations":"Target class refactored an instance field into a static one; copy-pasting a field name without checking its modifiers; using the helper to fetch constants or cached/singleton fields that are static.","solutions":["Make the field non-static in the target type if an instance field is genuinely intended","Use a static-field accessor (e.g. AccessTools.Field + fieldInfo.GetValue(null), or a static field ref helper) instead of GetInstanceField","Verify the field's modifiers with AccessTools.DeclaredField/fieldInfo.IsStatic before calling"],"exampleFix":"// before\nvar fi = Tools.GetInstanceField(typeof(Player), \"instanceCount\"); // instanceCount is static\n// after\nvar fi = typeof(Player).GetField(\"instanceCount\", BindingFlags.Static | BindingFlags.NonPublic);","handlingStrategy":"validation","validationCode":"var fi = AccessTools.Field(type, fieldName);\nif (fi == null) throw new MissingFieldException(type.Name, fieldName);\nif (fi.IsStatic) throw new ArgumentException($\"{type.Name}.{fieldName} is static; use a static field accessor\");","typeGuard":"bool IsInstanceField(Type t, string name) =>\n    t.GetField(name, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic) is { IsStatic: false };","tryCatchPattern":"try { var fi = Tools.GetInstanceField(type, fieldName); }\ncatch (ArgumentException ex) when (ex.Message == \"Field must not be static\") { /* fall back to static access */ }\ncatch (MissingFieldException) { /* field doesn't exist */ }","preventionTips":["Check fieldInfo.IsStatic before using instance-field helpers","Keep target-field lookups in one place so refactors in the patched library surface once","Prefer AccessTools helpers and verify with FieldExists"],"tags":["csharp","reflection","harmony"],"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"}