{"record":{"id":"43e52f33c5b12d1e","repo":"larksuite/cli","slug":"w-v","errorCode":null,"errorMessage":"%w: %v","messagePattern":"%w: %v","errorType":"exception","errorClass":"ErrMultipleRestricts","httpStatus":null,"severity":"error","filePath":"internal/cmdpolicy/resolver.go","lineNumber":54,"sourceCode":"\tYAMLRules   []*platform.Rule\n\tYAMLPath    string\n}\n\nvar ErrMultipleRestricts = errors.New(\"multiple plugins called Restrict; only one plugin may own the policy\")\n\n// Resolve picks by precedence: plugin > yaml > none, returning the full\n// 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}","sourceCodeStart":36,"sourceCodeEnd":72,"githubUrl":"https://github.com/larksuite/cli/blob/7fd6ef3c07182257ce776cdc5a614e122d5bd4b3/internal/cmdpolicy/resolver.go#L36-L72","documentation":"cmdpolicy.Resolve returns this error, wrapping ErrMultipleRestricts, when rules arrive from more than one DISTINCT plugin. Independent plugins cannot silently widen each other's policy, so the resolver deliberately aborts instead of merging. Note: multiple rules from a single plugin are fine; only multiple distinct plugin owners conflict.","triggerScenarios":"Applying user policy pruning where two or more different plugins each contributed PluginRules entries to Sources — e.g. loading several plugins that both register restrict rules.","commonSituations":"Installing multiple policy-enforcing plugins side by side, upgrading one plugin while an old policy plugin remains enabled, or composing plugin sets from different sources that both constrain commands.","solutions":["Remove or disable all but one plugin that contributes policy rules","Consolidate the restrict rules of the plugins into a single plugin's rule set","Move shared restrictions into the policy YAML (s.YAMLRules) instead of a second plugin, since a single YAML source is allowed alongside one plugin","Check plugin registration/config to find the conflicting plugin names listed in the error"],"exampleFix":"// before: two plugins register rules\npolicy.Resolve(cmdpolicy.Sources{PluginRules: rulesFromPluginA + rulesFromPluginB})\n// after: single plugin owner (or move extra rules to YAML)\npolicy.Resolve(cmdpolicy.Sources{PluginRules: rulesFromPluginA, YAMLRules: yamlRules, YAMLPath: \"policy.yaml\"})","handlingStrategy":"validation","validationCode":"owners := map[string]bool{}\nfor _, pr := range pluginRules { owners[pr.PluginName] = true }\nif len(owners) > 1 {\n    return fmt.Errorf(\"refusing to resolve: multiple policy plugins: %v\", owners)\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Enable at most one plugin that contributes policy rules","Move shared restrictions into the policy YAML instead of a second plugin","Audit installed plugins for policy contributors before composition","Treat multiple restrict sources as a configuration error in your tooling"],"tags":["config","plugins","policy"],"backgroundTag":"conflicting-policy-sources","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"}