larksuite/cli · error

plugin %q rule invalid: %w

Error message

plugin %q rule invalid: %w

What it means

Resolve validates each plugin-contributed rule with ValidateRule; this error wraps that validation failure and names the offending plugin. It means a plugin shipped a rule that violates the policy schema — most commonly an invalid max_risk value or a bad identities entry.

Source

Thrown at internal/cmdpolicy/resolver.go:61

// rule set the winning source contributes. Pure function; load yaml via
// LoadYAMLPolicy first. Every returned rule is validated.
//
// Multi-rule semantics (single owner): one plugin may contribute several
// rules (each a scoped grant, OR-combined by the engine), but two or more
// DISTINCT plugins contributing rules is still a configuration error --
// the resolver aborts so independent plugins cannot silently widen each
// other's policy. yaml may likewise carry several rules under "rules:".
func Resolve(s Sources) ([]*platform.Rule, ResolveSource, error) {
	owners := distinctOwners(s.PluginRules)
	if len(owners) > 1 {
		return nil, ResolveSource{}, fmt.Errorf("%w: %v", ErrMultipleRestricts, owners)
	}

	if len(s.PluginRules) > 0 {
		rules := make([]*platform.Rule, 0, len(s.PluginRules))
		for _, pr := range s.PluginRules {
			if err := ValidateRule(pr.Rule); err != nil {
				return nil, ResolveSource{}, fmt.Errorf("plugin %q rule invalid: %w", pr.PluginName, err)
			}
			rules = append(rules, pr.Rule)
		}
		return rules, ResolveSource{Kind: SourcePlugin, Name: owners[0]}, nil
	}

	if len(s.YAMLRules) > 0 {
		for _, r := range s.YAMLRules {
			if err := ValidateRule(r); err != nil {
				return nil, ResolveSource{}, fmt.Errorf("policy yaml %q: %w", s.YAMLPath, err)
			}
		}
		return s.YAMLRules, ResolveSource{Kind: SourceYAML, Name: s.YAMLPath}, nil
	}

	return nil, ResolveSource{Kind: SourceNone}, nil
}

View on GitHub (pinned to 7fd6ef3c07)

Solutions

  1. Read the wrapped cause: it names the exact invalid field (max_risk or identities)
  2. Fix the plugin's rule to use max_risk of read|write|high-risk-write
  3. Ensure each identities entry is exactly 'user' or 'bot'
  4. Update or reinstall the offending plugin if the rule comes from a distributed plugin

Example fix

// before (plugin rule)
{"max_risk": "rw", "identities": ["service"]}
// after
{"max_risk": "write", "identities": ["user"]}
Defensive patterns

Strategy: validation

Validate before calling

func validPluginRule(pr cmdpolicy.PluginRule) error {
    if pr.Rule != nil && pr.Rule.MaxRisk != "" &&
        pr.Rule.MaxRisk != "read" && pr.Rule.MaxRisk != "write" && pr.Rule.MaxRisk != "high-risk-write" {
        return fmt.Errorf("plugin %q: bad max_risk %q", pr.PluginName, pr.Rule.MaxRisk)
    }
    return nil
}

Type guard

func isIdentValid(s string) bool { return s == "user" || s == "bot" }

Prevention

When it happens

Trigger: Resolve encounters a PluginRules entry whose Rule fails ValidateRule (invalid MaxRisk enum, invalid identities value like 'service' instead of 'user'/'bot').

Common situations: A plugin authored with a typo'd max_risk (e.g. 'rw', 'WRITE'), a rule from an older policy schema version, or a hand-edited plugin rule file.

Related errors


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