larksuite/cli · error

policy yaml %q: %w

Error message

policy yaml %q: %w

What it means

Resolve validates each YAML policy rule with ValidateRule; a failure is wrapped as 'policy yaml %q: %w' naming the YAML file path. The same format is reused when parsing the YAML fails inside LoadYAMLPolicy, so this message can indicate either schema-invalid rules or unparseable YAML content.

Source

Thrown at internal/cmdpolicy/resolver.go:71

	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
}

// distinctOwners returns the unique plugin names contributing a rule, in
// first-seen order. A single plugin contributing N rules collapses to one
// owner; that is the case the single-owner check below permits.
func distinctOwners(prs []PluginRule) []string {
	seen := map[string]bool{}
	owners := make([]string, 0, len(prs))
	for _, pr := range prs {
		if !seen[pr.PluginName] {
			seen[pr.PluginName] = true
			owners = append(owners, pr.PluginName)

View on GitHub (pinned to 7fd6ef3c07)

Solutions

  1. Read the wrapped cause for the exact failing rule/field
  2. Fix max_risk to one of read|write|high-risk-write
  3. Ensure every identities entry is exactly 'user' or 'bot'
  4. Validate the YAML parses (yaml lint) and matches the expected policy rule schema

Example fix

// before (policy.yaml)
rules:
  - max_risk: "admin"
    identities: ["bot", "service"]
// after
rules:
  - max_risk: "high-risk-write"
    identities: ["bot"]
Defensive patterns

Strategy: validation

Validate before calling

func validateYAMLPolicy(path string) error {
    data, err := os.ReadFile(path)
    if err != nil { return err }
    rules, err := pyaml.Parse(data)
    if err != nil { return fmt.Errorf("policy yaml %q: %w", path, err) }
    for _, r := range rules {
        if err := cmdpolicy.ValidateRule(r); err != nil {
            return fmt.Errorf("policy yaml %q: %w", path, err)
        }
    }
    return nil
}

Prevention

When it happens

Trigger: Resolve with non-empty YAMLRules where any rule fails ValidateRule; or LoadYAMLPolicy feeding Resolve where pyaml.Parse fails on the file's contents.

Common situations: Hand-edited policy YAML with an invalid max_risk string or an identities entry other than 'user'/'bot', wrong YAML structure (rules not matching the expected schema), or malformed YAML syntax.

Related errors


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