{"record":{"id":"e942eef78a648a0a","repo":"HangfireIO/Hangfire","slug":"argument-count-must-be-equal-to-method-parameter-c","errorCode":null,"errorMessage":"Argument count must be equal to method parameter count.","messagePattern":"Argument count must be equal to method parameter count\\.","errorType":"exception","errorClass":"ArgumentException","httpStatus":null,"severity":"error","filePath":"src/Hangfire.Core/Common/Job.cs","lineNumber":507,"sourceCode":"\n            if (!method.DeclaringType.GetTypeInfo().IsAssignableFrom(type.GetTypeInfo()))\n            {\n                throw new ArgumentException(\n                    $\"The type `{method.DeclaringType}` must be derived from the `{type}` type.\",\n                    typeParameterName);\n            }\n\n            if (method.ReturnType == typeof(void) &&\n                AsyncStateMachineAttributeCache.GetOrAdd(method, static m => m.GetCustomAttribute<AsyncStateMachineAttribute>()) != null)\n            {\n                throw new NotSupportedException(\"Async void methods are not supported. Use async Task instead.\");\n            }\n\n            var parameters = method.GetParameters();\n\n            if (parameters.Length != argumentCount)\n            {\n                throw new ArgumentException(\n                    \"Argument count must be equal to method parameter count.\",\n                    argumentParameterName);\n            }\n\n            foreach (var parameter in parameters)\n            {\n                // There is no guarantee that specified method will be invoked\n                // in the same process. Therefore, output parameters and parameters\n                // passed by reference are not supported.\n\n                if (parameter.IsOut)\n                {\n                    throw new NotSupportedException(\n                        \"Output parameters are not supported: there is no guarantee that specified method will be invoked inside the same process.\");\n                }\n\n                if (parameter.ParameterType.IsByRef)\n                {","sourceCodeStart":489,"sourceCodeEnd":525,"githubUrl":"https://github.com/HangfireIO/Hangfire/blob/c236dd0f930f831ec151e436e138ddc429a02a72/src/Hangfire.Core/Common/Job.cs#L489-L525","documentation":"ArgumentException thrown by Job.Validate when method.GetParameters().Length != argumentCount — the number of arguments supplied to the Job constructor does not match the method's parameter count. Hangfire serializes arguments positionally and re-invokes by reflection, so a mismatch would cause a TargetParameterCountException at perform time; the validation catches it early at definition time. The parameter name reported is the argument array's name (e.g., 'args').","triggerScenarios":"Constructing new Job(type, method, new object[] { 1, 2 }) for a method with one parameter; passing too few/many args via reflection; a deserialized job whose stored arg count drifts from the method after a code change.","commonSituations":"Refactoring a job method to add/remove a parameter without migrating serialized jobs; building jobs from MethodInfo with a manually-constructed args array that is out of sync; version skew between the enqueueing process and the performing process.","solutions":["Align the args array length with method.GetParameters().Length.","Prefer Job.FromExpression which extracts arguments from the expression tree automatically, avoiding manual count errors.","When changing a job method signature, expire old jobs or keep an overload to avoid deserialization mismatches."],"exampleFix":"// before — count mismatch\nvar method = typeof(Worker).GetMethod(\"Run\"); // void Run(int a, int b)\nvar job = new Job(typeof(Worker), method, new object[] { 1 });\n\n// after — correct count\nvar job = new Job(typeof(Worker), method, new object[] { 1, 2 });\n// or let FromExpression handle it\nvar job = Job.FromExpression<Worker>(x => x.Run(1, 2));","handlingStrategy":"validation","validationCode":"if (method.GetParameters().Length != args.Length)\n    throw new ArgumentException($\"Argument count ({args.Length}) does not match method parameter count ({method.GetParameters().Length}).\");","typeGuard":"public static bool ArgumentCountMatches(MethodInfo method, IReadOnlyList<object> args)\n    => method != null && args != null && method.GetParameters().Length == args.Count;","tryCatchPattern":"try { var job = new Job(type, method, args); }\ncatch (ArgumentException ex) when (ex.Message.Contains(\"Argument count\")) { /* align args length with parameters */ }","preventionTips":["Prefer Job.FromExpression which extracts arguments from the expression tree automatically.","When building from MethodInfo, derive args length from method.GetParameters().Length.","When changing a job method signature, expire or migrate in-flight serialized jobs."],"tags":["argument","job-definition","argument-count","reflection"],"backgroundTag":null,"analyzedSha":"c236dd0f930f831ec151e436e138ddc429a02a72","analyzedAt":"2026-08-13T20:27:11.027Z","schemaVersion":2},"datasetVersion":"2026-08-14T00:17:13.853Z"}