larksuite/cli · error
parse policy yaml: multiple YAML documents are not allowed
Error message
parse policy yaml: multiple YAML documents are not allowed
What it means
After decoding the first document, Parse requires a second Decode to return io.EOF. If a second document decodes successfully, the input contained multiple '---'-separated documents. Since yaml.v3 decodes only one document per call, a trailing document would be silently dropped, so Parse rejects multi-document input explicitly.
Source
Thrown at internal/cmdpolicy/yaml/schema.go:114
//
// Semantic validation (MaxRisk taxonomy, identity values, glob syntax) is
// the caller's responsibility -- run each result through
// internal/cmdpolicy.ValidateRule before handing it to the engine.
func Parse(data []byte) ([]*platform.Rule, error) {
var s fileSchema
dec := gopkgyaml.NewDecoder(bytesReader(data))
dec.KnownFields(true)
if err := dec.Decode(&s); err != nil {
return nil, fmt.Errorf("parse policy yaml: %w", err)
}
// 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
}
View on GitHub (pinned to 7fd6ef3c07)
Solutions
- Remove the extra document and '---' separator so the file holds one document.
- Merge multiple rule sets into a single 'rules:' list.
- Split content into separate policy files and load each individually.
Example fix
// before name: a --- name: b // after rules: - name: a - name: b
Defensive patterns
Strategy: validation
Validate before calling
if bytes.Count(data, []byte("\n---")) > 0 {
return fmt.Errorf("policy file must contain exactly one YAML document")
} Try / catch
rules, err := yaml.Parse(data)
if err != nil && strings.Contains(err.Error(), "multiple YAML documents") {
return fmt.Errorf("split the file or merge into a single rules: list: %w", err)
} Prevention
- Never concatenate policy files with cat; merge rule lists instead.
- Strip '---' front-matter separators before loading generated files.
- Convert multi-document manifests into one document with a 'rules:' list.
- Add a pre-commit check rejecting '---' in policy files.
When it happens
Trigger: Calling Parse on bytes containing two documents separated by '---', e.g. concatenated policy files or a heredoc with a stray '---' separator.
Common situations: Appending policy files with cat; Kubernetes-style multi-document manifests pasted into a policy file; templates emitting leading '---' plus inner separators.
Related errors
- parse policy yaml: %w
- parse policy yaml: 'rules:' is present but empty; remove the
- parse policy yaml: top-level rule fields cannot be combined
- Invalid column: {column!r}
- Invalid column index: {index}
AI-assisted analysis of larksuite/cli@7fd6ef3c07 (2026-09-04).
Data as JSON: /api/errors/004f51866ededd89.
Report an issue: GitHub.