hyperledger/fabric · error
unrecognized type, expected the context, got %s
Error message
unrecognized type, expected the context, got %s
What it means
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>'.
Source
Thrown at common/policydsl/policyparser.go:139
return toret.String() + ")", nil
}
// secondPass processes a list of arguments to build a "t-out-of-n" policy.
// It expects the first argument to be a context, the second an integer (threshold t),
// and the rest as either principals (strings) or pre-existing policies.
func secondPass(args ...any) (any, error) {
/* general sanity check, we expect at least 3 args */
if len(args) < 3 {
return nil, fmt.Errorf("at least 3 arguments expected, got %d", len(args))
}
/* get the first argument, we expect it to be the context */
var ctx *context
switch v := args[0].(type) {
case *context:
ctx = v
default:
return nil, fmt.Errorf("unrecognized type, expected the context, got %s", reflect.TypeOf(args[0]))
}
/* get the second argument, we expect an integer telling us
how many of the remaining we expect to have*/
var t int
switch arg := args[1].(type) {
case float64:
t = int(arg)
case int:
t = arg
default:
return nil, fmt.Errorf("unrecognized type, expected a number, got %s", reflect.TypeOf(args[1]))
}
/* get the n in the t out of n */
n := len(args) - 2
/* sanity check - t should be positive, permit equal to n+1, but disallow over n+1 */View on GitHub (pinned to 2736b63f8f)
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.
Example fix
// before secondPass(nil, 1, "Org1.member") // after secondPass(policydsl.NewContextLike()) // or use policydsl.FromString which injects the context
Defensive patterns
Strategy: validation
Validate before calling
ctx := newContext() // allocate before use
if ctx == nil {
return fmt.Errorf("policy context must not be nil")
}
env := map[string]interface{}{"outof": secondPass, "ID": ctx} Type guard
func ensureContext(a any) (*context, bool) {
c, ok := a.(*context)
return c, ok && c != nil
} Try / catch
if err != nil && strings.Contains(err.Error(), "expected the context") {
return nil, fmt.Errorf("internal: policy pass missing ID context: %w", err)
} Prevention
- 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.
When it happens
Trigger: 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.
Common situations: 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.
Related errors
- unexpected type %s
- unrecognized type, expected a number, got %s
- expected at least two arguments to NOutOf. Given %d
- at least 3 arguments expected, got %d
- invalid t-out-of-n predicate, t %d, n %d
AI-assisted analysis of hyperledger/fabric@2736b63f8f (2026-09-04).
Data as JSON: /api/errors/b9a941ae8743257e.
Report an issue: GitHub.