{"record":{"id":"5a7a6d86950e1e7b","repo":"kataras/iris","slug":"args-len-d-should-be-the-same-len-as-numfields","errorCode":null,"errorMessage":"args(len=%d) should be the same len as numFields(%d) for: %s","messagePattern":"args\\(len=(.+?)\\) should be the same len as numFields\\((.+?)\\) for: (.+?)","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"macro/macro.go","lineNumber":137,"sourceCode":"\t\t\t\treturn fnV\n\t\t\t}\n\t\t}\n\n\t\treturn nil\n\t}\n\n\tnumFields := typFn.NumIn()\n\n\tpanicIfErr := func(i int, err error) {\n\t\tif err != nil {\n\t\t\tpanic(fmt.Sprintf(\"on field index: %d: %v\", i, err))\n\t\t}\n\t}\n\n\treturn func(args []string) reflect.Value {\n\t\tif len(args) != numFields {\n\t\t\t// no variadics support, for now.\n\t\t\tpanic(fmt.Sprintf(\"args(len=%d) should be the same len as numFields(%d) for: %s\", len(args), numFields, typFn))\n\t\t}\n\t\tvar argValues []reflect.Value\n\t\tfor i := 0; i < numFields; i++ {\n\t\t\tfield := typFn.In(i)\n\t\t\targ := args[i]\n\n\t\t\t// try to convert the string literal as we get it from the parser.\n\t\t\tvar (\n\t\t\t\tval any\n\t\t\t)\n\n\t\t\t// try to get the value based on the expected type.\n\t\t\tswitch field.Kind() {\n\t\t\tcase reflect.Int:\n\t\t\t\tv, err := strconv.Atoi(arg)\n\t\t\t\tpanicIfErr(i, err)\n\t\t\t\tval = v\n\t\t\tcase reflect.Int8:","sourceCodeStart":119,"sourceCodeEnd":155,"githubUrl":"https://github.com/kataras/iris/blob/7bedaf55a0b64bbb2248a5845a2c60d81a30996a/macro/macro.go#L119-L155","documentation":"A macro evaluator defined over a struct requires exactly one route argument per struct field; when the number of supplied arguments differs from the struct's field count, the route panics with 'args(len=%d) should be the same len as numFields(%d)' (macro/macro.go:137). Variadic argument counts are not supported.","triggerScenarios":"Registering a macro type whose evaluator function takes a struct with N fields, then using the type in a path with fewer or more than N arguments, e.g. {range:number 5} when the evaluator struct has two fields (min, max).","commonSituations":"Omitting one of the arguments (e.g. writing {ts:number 100} instead of {ts:number 100 200} for a min-max evaluator), or adding a field to the evaluator struct without updating every route using it.","solutions":["Supply exactly as many space-separated arguments in the path parameter as the evaluator struct has fields.","Reduce the evaluator struct to only the fields you actually pass in routes.","Update all routes that use this param type after changing the struct's field count."],"exampleFix":"// before (evaluator struct has Min and Max)\napp.Get(\"/{n:number 10}\", h)\n\n// after\napp.Get(\"/{n:number 1 10}\", h)","handlingStrategy":"validation","validationCode":"// Count fields of the evaluator struct and compare with args in the path\nt := reflect.TypeOf(MyEvaluator{})\nnArgs := len(strings.Fields(paramArgs))\nif nArgs != t.NumField() {\n    log.Fatalf(\"param needs %d args, got %d\", t.NumField(), nArgs)\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Provide exactly one argument per evaluator-struct field, in field order.","Grep routes after adding/removing evaluator fields and update all usages.","Document the required argument list next to the custom param type."],"tags":["go","panic","routing","path-parameters"],"backgroundTag":"macro-argument-count-mismatch","analyzedSha":"7bedaf55a0b64bbb2248a5845a2c60d81a30996a","analyzedAt":"2026-08-30T20:38:16.250Z","schemaVersion":2},"datasetVersion":"2026-08-30T23:17:21.991Z"}