larksuite/cli · error
parse policy yaml: top-level rule fields cannot be combined
Error message
parse policy yaml: top-level rule fields cannot be combined with a 'rules:' list; move every rule under 'rules:'
What it means
fileSchema accepts two mutually exclusive layouts: flat top-level rule fields (historical single-rule layout, inlined ruleSchema) or a 'rules:' list. Mixing both is ambiguous, so when 'rules:' is present and any flat field (name, allow, deny, max_risk, identities, allow_unannotated) is also set, Parse rejects the document instead of guessing intent.
Source
Thrown at internal/cmdpolicy/yaml/schema.go:124
}
// Reject multi-document input: yaml.v3 only decodes one document
// per call, so a stray "---" followed by another document would
// silently drop the trailing rule.
var extra fileSchema
if err := dec.Decode(&extra); !errors.Is(err, io.EOF) {
if err == nil {
return nil, fmt.Errorf("parse policy yaml: multiple YAML documents are not allowed")
}
return nil, fmt.Errorf("parse policy yaml: %w", err)
}
if s.Rules != nil {
if len(*s.Rules) == 0 {
return nil, fmt.Errorf("parse policy yaml: 'rules:' is present but empty; remove the key, or list at least one rule")
}
if !s.ruleSchema.isZero() {
return nil, fmt.Errorf("parse policy yaml: top-level rule fields cannot be combined with a 'rules:' list; move every rule under 'rules:'")
}
out := make([]*platform.Rule, 0, len(*s.Rules))
for _, rs := range *s.Rules {
out = append(out, rs.toRule())
}
return out, nil
}
// Backward-compatible single top-level rule (flat fields).
return []*platform.Rule{s.ruleSchema.toRule()}, nil
}
View on GitHub (pinned to 7fd6ef3c07)
Solutions
- Move every flat rule field into entries under 'rules:'.
- Or delete the 'rules:' key if the single flat rule is intended.
- Remove stale top-level keys left over from migration.
Example fix
// before
max_risk: read
rules:
- name: a
// after
rules:
- name: a
max_risk: read Defensive patterns
Strategy: validation
Validate before calling
var probe struct {
Rules []any `yaml:"rules"`
Name string `yaml:"name"`
Allow []string `yaml:"allow"`
}
if err := yaml.Unmarshal(data, &probe); err == nil && probe.Rules != nil && (probe.Name != "" || len(probe.Allow) > 0) {
return fmt.Errorf("mixed flat fields and rules: list")
} Try / catch
if _, err := yaml.Parse(data); err != nil && strings.Contains(err.Error(), "cannot be combined") {
return fmt.Errorf("migrate fully to the rules: layout: %w", err)
} Prevention
- Pick one layout per file; prefer the 'rules:' list for new policies.
- When migrating a flat file, move every field under 'rules:' in the same edit.
- Watch for merge conflicts that re-introduce flat fields above a rules list.
- Lint policy files to fail on top-level rule keys when 'rules:' is present.
When it happens
Trigger: Calling Parse on YAML that has both a 'rules:' list and at least one top-level rule field, e.g. 'max_risk: read' at the top plus a 'rules:' list, or a leftover top-level 'name:' alongside rules.
Common situations: Migrating a flat single-rule file to the multi-rule layout without moving old flat fields under 'rules:'; merge-conflict resolutions keeping both styles; appending a rules list to an existing flat policy file.
Related errors
- parse policy yaml: %w
- parse policy yaml: multiple YAML documents are not allowed
- parse policy yaml: 'rules:' is present but empty; remove the
- Invalid column: {column!r}
- Invalid column index: {index}
AI-assisted analysis of larksuite/cli@7fd6ef3c07 (2026-09-04).
Data as JSON: /api/errors/4ba686218cf8a268.
Report an issue: GitHub.