larksuite/cli · error

parse policy yaml: %w

Error message

parse policy yaml: %w

What it means

Parse in internal/cmdpolicy/yaml/schema.go decodes policy YAML with KnownFields(true) (strict mode). Any yaml.v3 decode failure — syntax error, unknown field, or type mismatch — is wrapped as 'parse policy yaml: %w'. Strict mode is deliberate: an old binary must not silently ignore newly added schema fields.

Source

Thrown at internal/cmdpolicy/yaml/schema.go:105

}

// Parse decodes yaml bytes into one or more *platform.Rule. Unknown fields
// are rejected so an old binary cannot silently ignore new schema additions
// (forward-compat safeguard).
//
// The result always has at least one element: a flat-fields document
// yields a single rule (possibly an all-zero "no restriction" rule), and a
// "rules:" list yields one rule per entry.
//
// 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() {

View on GitHub (pinned to 7fd6ef3c07)

Solutions

  1. Read the wrapped yaml.v3 error (after %w) for the exact line/column and fix it there.
  2. Convert tabs to spaces — yaml.v3 rejects tab indentation.
  3. Diff keys against the schema: name, description, allow, deny, max_risk, identities, allow_unannotated, rules.
  4. If the file is from a newer CLI version, upgrade the binary.

Example fix

// before (policy.yaml)
rules:
	- name: x
// after
rules:
  - name: x   # spaces, not tabs
Defensive patterns

Strategy: try-catch

Validate before calling

var v map[string]any
if err := yaml.Unmarshal(data, &v); err != nil {
	return fmt.Errorf("policy yaml not parseable: %w", err)
}

Try / catch

rules, err := yaml.Parse(data)
if err != nil {
	var yamlErr *gopkgyaml.TypeError
	if errors.As(err, &yamlErr) {
		// surface line/column details from yamlErr
	}
	return fmt.Errorf("policy file rejected: %w", err)
}

Prevention

When it happens

Trigger: Calling Parse with bytes that are not valid YAML (bad indentation, tabs, unbalanced quotes), or YAML containing a field not in the schema (e.g. 'maximun_risk:' instead of 'max_risk:').

Common situations: Tabs instead of spaces in YAML; typo'd keys rejected as unknown fields; policies written for a newer CLI version with fields this binary does not know; missing colons or mis-nested lists.

Related errors


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