{"record":{"id":"4651223f6f7d8738","repo":"larksuite/cli","slug":"plugin-q-rule-invalid-w","errorCode":null,"errorMessage":"plugin %q rule invalid: %w","messagePattern":"plugin %q rule invalid: %w","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/cmdpolicy/resolver.go","lineNumber":61,"sourceCode":"// rule set the winning source contributes. Pure function; load yaml via\n// LoadYAMLPolicy first. Every returned rule is validated.\n//\n// Multi-rule semantics (single owner): one plugin may contribute several\n// rules (each a scoped grant, OR-combined by the engine), but two or more\n// DISTINCT plugins contributing rules is still a configuration error --\n// the resolver aborts so independent plugins cannot silently widen each\n// other's policy. yaml may likewise carry several rules under \"rules:\".\nfunc Resolve(s Sources) ([]*platform.Rule, ResolveSource, error) {\n\towners := distinctOwners(s.PluginRules)\n\tif len(owners) > 1 {\n\t\treturn nil, ResolveSource{}, fmt.Errorf(\"%w: %v\", ErrMultipleRestricts, owners)\n\t}\n\n\tif len(s.PluginRules) > 0 {\n\t\trules := make([]*platform.Rule, 0, len(s.PluginRules))\n\t\tfor _, pr := range s.PluginRules {\n\t\t\tif err := ValidateRule(pr.Rule); err != nil {\n\t\t\t\treturn nil, ResolveSource{}, fmt.Errorf(\"plugin %q rule invalid: %w\", pr.PluginName, err)\n\t\t\t}\n\t\t\trules = append(rules, pr.Rule)\n\t\t}\n\t\treturn rules, ResolveSource{Kind: SourcePlugin, Name: owners[0]}, nil\n\t}\n\n\tif len(s.YAMLRules) > 0 {\n\t\tfor _, r := range s.YAMLRules {\n\t\t\tif err := ValidateRule(r); err != nil {\n\t\t\t\treturn nil, ResolveSource{}, fmt.Errorf(\"policy yaml %q: %w\", s.YAMLPath, err)\n\t\t\t}\n\t\t}\n\t\treturn s.YAMLRules, ResolveSource{Kind: SourceYAML, Name: s.YAMLPath}, nil\n\t}\n\n\treturn nil, ResolveSource{Kind: SourceNone}, nil\n}\n","sourceCodeStart":43,"sourceCodeEnd":79,"githubUrl":"https://github.com/larksuite/cli/blob/7fd6ef3c07182257ce776cdc5a614e122d5bd4b3/internal/cmdpolicy/resolver.go#L43-L79","documentation":"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.","triggerScenarios":"Resolve encounters a PluginRules entry whose Rule fails ValidateRule (invalid MaxRisk enum, invalid identities value like 'service' instead of 'user'/'bot').","commonSituations":"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.","solutions":["Read the wrapped cause: it names the exact invalid field (max_risk or identities)","Fix the plugin's rule to use max_risk of read|write|high-risk-write","Ensure each identities entry is exactly 'user' or 'bot'","Update or reinstall the offending plugin if the rule comes from a distributed plugin"],"exampleFix":"// before (plugin rule)\n{\"max_risk\": \"rw\", \"identities\": [\"service\"]}\n// after\n{\"max_risk\": \"write\", \"identities\": [\"user\"]}","handlingStrategy":"validation","validationCode":"func validPluginRule(pr cmdpolicy.PluginRule) error {\n    if pr.Rule != nil && pr.Rule.MaxRisk != \"\" &&\n        pr.Rule.MaxRisk != \"read\" && pr.Rule.MaxRisk != \"write\" && pr.Rule.MaxRisk != \"high-risk-write\" {\n        return fmt.Errorf(\"plugin %q: bad max_risk %q\", pr.PluginName, pr.Rule.MaxRisk)\n    }\n    return nil\n}","typeGuard":"func isIdentValid(s string) bool { return s == \"user\" || s == \"bot\" }","tryCatchPattern":null,"preventionTips":["Test plugin rules with ValidateRule before shipping the plugin","Use only lowercase read|write|high-risk-write for max_risk","Keep identities limited to 'user' and 'bot'","Validate rules after plugin upgrades or schema changes"],"tags":["validation","policy","plugins"],"backgroundTag":"rule-validation-failed","analyzedSha":"7fd6ef3c07182257ce776cdc5a614e122d5bd4b3","analyzedAt":"2026-09-04T21:17:44.649Z","contentChangedAt":"2026-09-04T21:17:44.649Z","schemaVersion":2},"datasetVersion":"2026-09-12T02:17:10.037Z"}