{"record":{"id":"b9a941ae8743257e","repo":"hyperledger/fabric","slug":"unrecognized-type-expected-the-context-got-s","errorCode":null,"errorMessage":"unrecognized type, expected the context, got %s","messagePattern":"unrecognized type, expected the context, got (.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"common/policydsl/policyparser.go","lineNumber":139,"sourceCode":"\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:\n\t\tt = arg\n\tdefault:\n\t\treturn nil, fmt.Errorf(\"unrecognized type, expected a number, got %s\", reflect.TypeOf(args[1]))\n\t}\n\n\t/* get the n in the t out of n */\n\tn := len(args) - 2\n\n\t/* sanity check - t should be positive, permit equal to n+1, but disallow over n+1 */","sourceCodeStart":121,"sourceCodeEnd":157,"githubUrl":"https://github.com/hyperledger/fabric/blob/2736b63f8fd5932511d56fe68b7039d15977f7f6/common/policydsl/policyparser.go#L121-L157","documentation":"secondPass expects its first argument to be the internal *context that accumulates principals and assigns identity IDs (injected as 'ID' by FromString). If args[0] is anything else, the pass cannot track principals and returns 'unrecognized type, expected the context, got <T>'.","triggerScenarios":"Calling secondPass directly with a non-context first argument (e.g. a string, nil, or a value *context), or an environment map for the expr pass where 'ID' is missing/overridden so the first positional argument is something else.","commonSituations":"Custom tooling that re-implements the FromString pipeline but forgets to register the ID context in the expr env; tests invoking secondPass with hand-built argument lists; copying code from older Fabric versions where the signature differed.","solutions":["Always obtain the context via newContext() and pass it (or register it as env key \"ID\") as the first argument: secondPass(newContext(), t, principals...).","If replicating FromString, build env as map[string]interface{}{\"outof\": secondPass, \"ID\": ctx}.","Check for nil being passed as the context — allocate it explicitly.","Verify no code between passes replaces the 'ID' env entry."],"exampleFix":"// before\nsecondPass(nil, 1, \"Org1.member\")\n// after\nsecondPass(policydsl.NewContextLike()) // or use policydsl.FromString which injects the context","handlingStrategy":"validation","validationCode":"ctx := newContext() // allocate before use\nif ctx == nil {\n\treturn fmt.Errorf(\"policy context must not be nil\")\n}\nenv := map[string]interface{}{\"outof\": secondPass, \"ID\": ctx}","typeGuard":"func ensureContext(a any) (*context, bool) {\n\tc, ok := a.(*context)\n\treturn c, ok && c != nil\n}","tryCatchPattern":"if err != nil && strings.Contains(err.Error(), \"expected the context\") {\n\treturn nil, fmt.Errorf(\"internal: policy pass missing ID context: %w\", err)\n}","preventionTips":["Always build the second-pass env with both \"outof\" and \"ID\" keys.","Never pass nil as the context; use newContext().","Use FromString rather than reimplementing the multi-pass pipeline."],"tags":["policydsl","hyperledger-fabric","type-error","internal-context"],"backgroundTag":"unexpected-argument-type","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"}