{"record":{"id":"4169e91af4d46e4b","repo":"larksuite/cli","slug":"parse-policy-yaml-w","errorCode":null,"errorMessage":"parse policy yaml: %w","messagePattern":"parse policy yaml: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/cmdpolicy/yaml/schema.go","lineNumber":105,"sourceCode":"}\n\n// Parse decodes yaml bytes into one or more *platform.Rule. Unknown fields\n// are rejected so an old binary cannot silently ignore new schema additions\n// (forward-compat safeguard).\n//\n// The result always has at least one element: a flat-fields document\n// yields a single rule (possibly an all-zero \"no restriction\" rule), and a\n// \"rules:\" list yields one rule per entry.\n//\n// Semantic validation (MaxRisk taxonomy, identity values, glob syntax) is\n// the caller's responsibility -- run each result through\n// internal/cmdpolicy.ValidateRule before handing it to the engine.\nfunc Parse(data []byte) ([]*platform.Rule, error) {\n\tvar s fileSchema\n\tdec := gopkgyaml.NewDecoder(bytesReader(data))\n\tdec.KnownFields(true)\n\tif err := dec.Decode(&s); err != nil {\n\t\treturn nil, fmt.Errorf(\"parse policy yaml: %w\", err)\n\t}\n\n\t// Reject multi-document input: yaml.v3 only decodes one document\n\t// per call, so a stray \"---\" followed by another document would\n\t// silently drop the trailing rule.\n\tvar extra fileSchema\n\tif err := dec.Decode(&extra); !errors.Is(err, io.EOF) {\n\t\tif err == nil {\n\t\t\treturn nil, fmt.Errorf(\"parse policy yaml: multiple YAML documents are not allowed\")\n\t\t}\n\t\treturn nil, fmt.Errorf(\"parse policy yaml: %w\", err)\n\t}\n\n\tif s.Rules != nil {\n\t\tif len(*s.Rules) == 0 {\n\t\t\treturn nil, fmt.Errorf(\"parse policy yaml: 'rules:' is present but empty; remove the key, or list at least one rule\")\n\t\t}\n\t\tif !s.ruleSchema.isZero() {","sourceCodeStart":87,"sourceCodeEnd":123,"githubUrl":"https://github.com/larksuite/cli/blob/7fd6ef3c07182257ce776cdc5a614e122d5bd4b3/internal/cmdpolicy/yaml/schema.go#L87-L123","documentation":"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.","triggerScenarios":"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:').","commonSituations":"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.","solutions":["Read the wrapped yaml.v3 error (after %w) for the exact line/column and fix it there.","Convert tabs to spaces — yaml.v3 rejects tab indentation.","Diff keys against the schema: name, description, allow, deny, max_risk, identities, allow_unannotated, rules.","If the file is from a newer CLI version, upgrade the binary."],"exampleFix":"// before (policy.yaml)\nrules:\n\t- name: x\n// after\nrules:\n  - name: x   # spaces, not tabs","handlingStrategy":"try-catch","validationCode":"var v map[string]any\nif err := yaml.Unmarshal(data, &v); err != nil {\n\treturn fmt.Errorf(\"policy yaml not parseable: %w\", err)\n}","typeGuard":null,"tryCatchPattern":"rules, err := yaml.Parse(data)\nif err != nil {\n\tvar yamlErr *gopkgyaml.TypeError\n\tif errors.As(err, &yamlErr) {\n\t\t// surface line/column details from yamlErr\n\t}\n\treturn fmt.Errorf(\"policy file rejected: %w\", err)\n}","preventionTips":["Use spaces, never tabs, for YAML indentation.","Validate policy files with the CLI validate subcommand in CI.","Pin the CLI version that matches the policy schema you write against.","Keep keys within the documented schema: name, description, allow, deny, max_risk, identities, allow_unannotated, rules."],"tags":["go","yaml","parsing","config"],"backgroundTag":"yaml-parse-error","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"}