larksuite/cli · error

Restrict(nil): rule must not be nil

Error message

Restrict(nil): rule must not be nil

What it means

The Builder's Restrict() method was called with a nil *Rule. The builder collects errors into b.errs instead of panicking so chained construction can report all problems at Build() time. A nil rule cannot express any capability restriction, so the call is rejected.

Source

Thrown at extension/platform/builder.go:138

	if !b.validateHookName(hookName, "on") {
		return b
	}
	e, n, f := event, hookName, fn
	b.actions = append(b.actions, func(r Registrar) {
		r.On(e, n, f)
	})
	return b
}

// Restrict contributes a pruning Rule. Calling Restrict implicitly
// sets Restricts=true and FailurePolicy=FailClosed (the framework
// requires both to coexist; the builder enforces the pairing so the
// plugin author cannot accidentally ship a policy plugin under
// FailOpen). It may be called more than once; each call adds one scoped
// Rule and the engine OR-combines them.
func (b *Builder) Restrict(rule *Rule) *Builder {
	if rule == nil {
		b.errs = append(b.errs, errors.New("Restrict(nil): rule must not be nil"))
		return b
	}
	b.caps.Restricts = true
	b.caps.FailurePolicy = FailClosed
	// Defensive clone: capture an independent snapshot so a caller that
	// reuses and mutates the same *Rule across multiple Restrict calls
	// gets distinct entries (mirrors the staging registrar's clone).
	cp := *rule
	cp.Allow = append([]string(nil), rule.Allow...)
	cp.Deny = append([]string(nil), rule.Deny...)
	cp.Identities = append([]Identity(nil), rule.Identities...)
	b.rules = append(b.rules, &cp)
	return b
}

// EmbeddedSkills contributes a SkillsOverlay (see SkillsOverlay) customizing
// the CLI's embedded skill content. It implies FailClosed: although skill
// content is not a command-enforcement boundary, the overlay is a distribution

View on GitHub (pinned to 7fd6ef3c07)

Solutions

  1. Construct a valid *Rule before calling Restrict, or skip the Restrict call entirely when no rule is needed
  2. Check the rule-producing function's error/nil return before passing its result to Restrict
  3. Call Build() and inspect the joined error; b.errs accumulates, so fix the nil input and rebuild

Example fix

// before
var rule *Rule
b.Restrict(rule) // panics-free but records error

// after
if rule != nil {
    b = b.Restrict(rule)
}
Defensive patterns

Strategy: validation

Validate before calling

if rule == nil {
    return nil, fmt.Errorf("cannot build plugin: restrict rule is nil")
}
b := builder.Restrict(rule)

Type guard

func hasRule(r *Rule) bool { return r != null() }

Prevention

When it happens

Trigger: Calling builder.Restrict(nil), typically because a *Rule variable is nil (uninitialized pointer, a function that returned nil on failure, or a conditional that left the rule unset).

Common situations: Config parsing produced no rule but the code still calls Restrict(rule); refactoring moved rule construction and left a nil default; optional rule built only under a feature flag that is off.

Related errors


AI-assisted analysis of larksuite/cli@7fd6ef3c07 (2026-09-04). Data as JSON: /api/errors/985a3cca132d0154. Report an issue: GitHub.