hyperledger/fabric · error
expected at least two arguments to NOutOf. Given %d
Error message
expected at least two arguments to NOutOf. Given %d
What it means
policydsl.outof() builds the intermediate 'outof(t, ...)' string used to convert a policy DSL expression into a SignaturePolicy. It requires at least two arguments: the threshold t and at least one principal/policy. Fewer than two arguments means a t-out-of-n policy with no subjects, which is meaningless, so the library rejects it.
Source
Thrown at common/policydsl/policyparser.go:53
RoleOrderer = "orderer"
)
var (
regex = regexp.MustCompile(
fmt.Sprintf("^([[:alnum:].-]+)([.])(%s|%s|%s|%s|%s)$",
RoleAdmin, RoleMember, RoleClient, RolePeer, RoleOrderer),
)
regexErr = regexp.MustCompile("^No parameter '([^']+)' found[.]$")
)
// a stub function - it returns the same string as it's passed.
// This will be evaluated by second/third passes to convert to a proto policy
func outof(args ...any) (any, error) {
var toret strings.Builder
toret.WriteString("outof(")
if len(args) < 2 {
return nil, fmt.Errorf("expected at least two arguments to NOutOf. Given %d", len(args))
}
arg0 := args[0]
// govaluate treats all numbers as float64 only. But and/or may pass int/string. Allowing int/string for flexibility of caller
if n, ok := arg0.(float64); ok {
toret.WriteString(strconv.Itoa(int(n)))
} else if n, ok := arg0.(int); ok {
toret.WriteString(strconv.Itoa(n))
} else if n, ok := arg0.(string); ok {
toret.WriteString(n)
} else {
return nil, fmt.Errorf("unexpected type %s", reflect.TypeOf(arg0))
}
for _, arg := range args[1:] {
toret.WriteString(", ")
switch t := arg.(type) {View on GitHub (pinned to 2736b63f8f)
Solutions
- Ensure OutOf is called with at least one subject: OutOf(t, principal1[, principal2...]).
- Check the policy string passed to FromString and add the missing principal(s), e.g. 'OutOf(1, "Org1.member")'.
- If principals are built dynamically, validate that the list is non-empty before calling OutOf; fall back to a default policy or return a config error.
- If you only need a single-subject policy, use SignedBy directly instead of OutOf.
Example fix
// before
policy, err := policydsl.FromString("OutOf(1)")
// after
policy, err := policydsl.FromString("OutOf(1, 'Org1.member')") Defensive patterns
Strategy: validation
Validate before calling
func validateGateArgs(t any, principals ...string) error {
if len(principals) < 1 {
return fmt.Errorf("OutOf requires at least one principal")
}
return nil
} Type guard
func hasMinArgs(args []any, n int) bool { return len(args) >= n } Try / catch
policy, err := policydsl.FromString(spec)
if err != nil {
if strings.Contains(err.Error(), "expected at least two arguments to NOutOf") {
return nil, fmt.Errorf("policy %q has a gate with no subjects: %w", spec, err)
}
return nil, err
} Prevention
- Always pass at least one principal after the threshold in OutOf/And/Or gates.
- Validate dynamically built principal lists are non-empty before composing the policy string.
- Quote principals in policy strings: OutOf(1, 'Org1.member').
- Add unit tests for every policy string shipped in config.
When it happens
Trigger: Calling OutOf(t) with zero or one additional subject (e.g. OutOf(1) or OutOf()), or a policy string like 'OutOf(1)' evaluated via FromString so that and/or/outof receives fewer than 2 args.
Common situations: Hand-written policy strings missing subjects ('OutOf(2)') after an editor stripped a trailing principal; programmatic builders that append principals conditionally and end up empty (e.g. empty channel/application org list); typos like 'OutOf(2,)' that the expr parser drops.
Related errors
- at least 3 arguments expected, got %d
- unexpected type %s
- unrecognized type, expected the context, got %s
- unrecognized type, expected a number, got %s
- 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/a193d905131ed44d.
Report an issue: GitHub.