{"record":{"id":"4e5e0c1d6cb93111","repo":"hyperledger/fabric","slug":"at-least-3-arguments-expected-got-d","errorCode":null,"errorMessage":"at least 3 arguments expected, got %d","messagePattern":"at least 3 arguments expected, got (.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"common/policydsl/policyparser.go","lineNumber":130,"sourceCode":"\t\tcase float64:\n\t\t\ttoret.WriteString(strconv.Itoa(int(t)))\n\t\tcase int:\n\t\t\ttoret.WriteString(strconv.Itoa(t))\n\t\tdefault:\n\t\t\treturn nil, fmt.Errorf(\"unexpected type %s\", reflect.TypeOf(arg))\n\t\t}\n\t}\n\n\treturn toret.String() + \")\", nil\n}\n\n// secondPass processes a list of arguments to build a \"t-out-of-n\" policy.\n// It expects the first argument to be a context, the second an integer (threshold t),\n// and the rest as either principals (strings) or pre-existing policies.\nfunc secondPass(args ...any) (any, error) {\n\t/* general sanity check, we expect at least 3 args */\n\tif len(args) < 3 {\n\t\treturn nil, fmt.Errorf(\"at least 3 arguments expected, got %d\", len(args))\n\t}\n\n\t/* get the first argument, we expect it to be the context */\n\tvar ctx *context\n\tswitch v := args[0].(type) {\n\tcase *context:\n\t\tctx = v\n\tdefault:\n\t\treturn nil, fmt.Errorf(\"unrecognized type, expected the context, got %s\", reflect.TypeOf(args[0]))\n\t}\n\n\t/* get the second argument, we expect an integer telling us\n\t   how many of the remaining we expect to have*/\n\tvar t int\n\tswitch arg := args[1].(type) {\n\tcase float64:\n\t\tt = int(arg)\n\tcase int:","sourceCodeStart":112,"sourceCodeEnd":148,"githubUrl":"https://github.com/hyperledger/fabric/blob/2736b63f8fd5932511d56fe68b7039d15977f7f6/common/policydsl/policyparser.go#L112-L148","documentation":"secondPass converts the intermediate outof string into an actual NOutOf SignaturePolicy. It needs at least 3 arguments: the injected ID context, the threshold t, and at least one principal/policy. Fewer than 3 means the intermediate structure was truncated or bypassed, so the pass aborts.","triggerScenarios":"An intermediate string like 'outof(ID)' or 'outof(ID, 1)' reaching the second pass — e.g. the original policy had a gate with no subjects (related to error 350 but caught later), or secondPass invoked directly with too few args.","commonSituations":"Empty org lists in generated policy code producing subject-less gates; custom pipelines that call secondPass without the injected ID argument; policy strings mangled by templating that dropped trailing arguments.","solutions":["Ensure the original policy gate has at least one subject: 'OutOf(1, \"Org1.member\")'.","If calling secondPass directly, pass (ctx *context, t int, principal-or-policy, ...).","Validate generated policy strings contain at least one principal per gate before invoking FromString.","Trace where the intermediate 'outof(...)' string is produced; fix the upstream missing-argument bug."],"exampleFix":"// before\npolicydsl.FromString(\"And()\") // gate with no subjects\n// after\npolicydsl.FromString(\"And('Org1.member', 'Org2.member')\")","handlingStrategy":"validation","validationCode":"if len(args) < 3 {\n\treturn fmt.Errorf(\"secondPass needs ctx, t, and at least one principal\")\n}\nctx, ok := args[0].(*context)\nif !ok {\n\treturn fmt.Errorf(\"first arg must be *context\")\n}","typeGuard":"func isContextCall(args []any) bool {\n\tif len(args) < 3 { return false }\n\t_, ok := args[0].(*context)\n\treturn ok\n}","tryCatchPattern":"policy, err := policydsl.FromString(spec)\nif err != nil && strings.Contains(err.Error(), \"at least 3 arguments expected\") {\n\treturn nil, fmt.Errorf(\"policy %q has an empty gate: %w\", spec, err)\n}","preventionTips":["Never call secondPass directly; go through FromString which injects the ID context.","Ensure every gate in the policy string has at least one principal.","Validate generated policies with a pre-parse sanity check on gate arity."],"tags":["policydsl","hyperledger-fabric","argument-count","signature-policy"],"backgroundTag":"invalid-function-arity","analyzedSha":"2736b63f8fd5932511d56fe68b7039d15977f7f6","analyzedAt":"2026-09-04T08:52:36.465Z","contentChangedAt":"2026-09-04T08:52:36.465Z","schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}