pardeike/Harmony · error · ArgumentException
Using requires an additional attribute for specifying the…
Error message
Using {PatchTools.harmonyPatchAllFullName} requires an additional attribute for specifying the Class/Type What it means
[HarmonyPatchAll] tells Harmony to patch many methods at once, but it does not say on which class those methods live. When the patch class does not also declare a declaring type (via [HarmonyPatch(typeof(...))] on the class or Harmony.CreateAndPatchAll(type, type)), GetBulkMethods throws.
Solutions
- Add a class-level attribute specifying the target type: [HarmonyPatch(typeof(TargetClass))] alongside [HarmonyPatchAll]
- Or call Harmony.CreateAndPatchAll(typeof(YourPatchClass), "id") so the declaring type is explicit
- Or drop [HarmonyPatchAll] and specify each target with per-method attributes
Example fix
// before
[HarmonyPatchAll]
class Patches { static void Postfix() { } }
// after
[HarmonyPatchAll]
[HarmonyPatch(typeof(TargetClass))]
class Patches { static void Postfix() { } } Defensive patterns
Strategy: validation
Validate before calling
if (type.GetCustomAttributes(true).Any(a => a.GetType().FullName == PatchTools.harmonyPatchAllFullName)
&& !type.GetCustomAttributes(true).Any(a => a is HarmonyAttribute && ((HarmonyAttribute)a).info.declaringType != null))
throw new Exception("HarmonyPatchAll needs a class-level HarmonyPatch(typeof(...))"); Prevention
- Always pair [HarmonyPatchAll] with a class-level declaring-type attribute
- Prefer Harmony.CreateAndPatchAll(patchType, id) for explicitness
When it happens
Trigger: Calling PatchAll on a class marked only with [HarmonyPatchAll] without any [HarmonyPatch(typeof(X))] class-level attribute, or Harmony.PatchAll() where the container type has no declaring type attribute.
Common situations: Copy-pasting a [HarmonyPatchAll] class and dropping the class-level [HarmonyPatch(typeof(...))] line; writing patch classes with only method-level attributes plus HarmonyPatchAll.
Understand the failure class
Background: "missing required argument" and "the following required arguments were not provided": what required-argument errors mean and how to fix them — this error's family across 20 libraries.
Related errors
- [ ]
- Ambiguous match for HarmonyMethod
- VariableState: variable of type
- VariableState: variable named
- argumentVariations contains more elements than argumentTypes
AI-assisted analysis of pardeike/Harmony@e7872dc170 (2026-09-15).
Data as JSON: /api/errors/9988bf0ea93917f1.
Report an issue: GitHub.
Appendix: source
Thrown at Harmony/Public/PatchClassProcessor.cs:251
job.postfixes.Do(patch => patchInfo.RemovePatch(patch.method));
job.prefixes.Do(patch => patchInfo.RemovePatch(patch.method));
}
job.transpilers.Do(patch => patchInfo.RemovePatch(patch.method));
if (hasBody)
job.finalizers.Do(patch => patchInfo.RemovePatch(patch.method));
var replacement = PatchFunctions.UpdateWrapper(job.original, patchInfo);
HarmonySharedState.UpdatePatchInfo(job.original, replacement, patchInfo);
}
List<MethodBase> GetBulkMethods()
{
var isPatchAll = containerType.GetCustomAttributes(true).Any(a => a.GetType().FullName == PatchTools.harmonyPatchAllFullName);
if (isPatchAll)
{
var type = containerAttributes.declaringType;
if (type is null)
throw new ArgumentException($"Using {PatchTools.harmonyPatchAllFullName} requires an additional attribute for specifying the Class/Type");
var list = new List<MethodBase>();
list.AddRange(AccessTools.GetDeclaredConstructors(type).Cast<MethodBase>());
list.AddRange(AccessTools.GetDeclaredMethods(type).Cast<MethodBase>());
var props = AccessTools.GetDeclaredProperties(type);
list.AddRange(props.Select(prop => prop.GetGetMethod(true)).Where(method => method is not null).Cast<MethodBase>());
list.AddRange(props.Select(prop => prop.GetSetMethod(true)).Where(method => method is not null).Cast<MethodBase>());
return list;
}
var result = new List<MethodBase>();
var targetMethods = RunMethod<HarmonyTargetMethods, IEnumerable<MethodBase>>(null, null);
if (targetMethods is object)
{
string error = null;
result = [.. targetMethods];
if (result is null)
View on GitHub (pinned to e7872dc170)