{"record":{"id":"d475b19d4f06d54f","repo":"larksuite/cli","slug":"l2-required-key-q-in-q-not-found-in-its-propert","errorCode":null,"errorMessage":"L2: required key %q in %q not found in its properties","messagePattern":"L2: required key %q in %q not found in its properties","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/schema/lint.go","lineNumber":134,"sourceCode":"func walkForL2(props *OrderedProps, errs *[]error) {\n\tif props == nil {\n\t\treturn\n\t}\n\tfor _, k := range props.Order {\n\t\tp := props.Map[k]\n\t\tif p.Format == \"binary\" && p.Type != \"string\" {\n\t\t\t*errs = append(*errs, fmt.Errorf(\"L2: field %q has format: binary but type = %q (want string)\", k, p.Type))\n\t\t}\n\t\tif p.Minimum != nil && p.Maximum != nil && *p.Minimum >= *p.Maximum {\n\t\t\t*errs = append(*errs, fmt.Errorf(\"L2: field %q minimum (%v) >= maximum (%v)\", k, *p.Minimum, *p.Maximum))\n\t\t}\n\t\tif n := len(p.EnumDescriptions); n > 0 && n != len(p.Enum) {\n\t\t\t*errs = append(*errs, fmt.Errorf(\"L2: field %q enumDescriptions length (%d) != enum length (%d)\", k, n, len(p.Enum)))\n\t\t}\n\t\tif len(p.Required) > 0 && p.Properties != nil {\n\t\t\tfor _, r := range p.Required {\n\t\t\t\tif _, ok := p.Properties.Map[r]; !ok {\n\t\t\t\t\t*errs = append(*errs, fmt.Errorf(\"L2: required key %q in %q not found in its properties\", r, k))\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tif p.Properties != nil {\n\t\t\twalkForL2(p.Properties, errs)\n\t\t}\n\t}\n}\n\n// validatePropertyTypes walks an OrderedProps tree and asserts:\n//   - every Property.Type is in validJSONSchemaTypes (or empty for nested objects with only properties)\n//   - array Properties have Items\n//\n// Errors are appended to *errs.\nfunc validatePropertyTypes(props *OrderedProps, errs *[]error) {\n\tif props == nil {\n\t\treturn\n\t}","sourceCodeStart":116,"sourceCodeEnd":152,"githubUrl":"https://github.com/larksuite/cli/blob/7fd6ef3c07182257ce776cdc5a614e122d5bd4b3/internal/schema/lint.go#L116-L152","documentation":"L2 schema lint failure: an object's required list names a key that does not exist in its properties. The sub-object required-exists invariant guarantees required keys are declared fields.","triggerScenarios":"walkForL2 visits a property p with non-empty p.Required and non-nil p.Properties, and a required key r is not found in p.Properties.Map.","commonSituations":"Renaming a property without updating the required list; copying required keys from the parent object into a nested object; upstream metadata listing a field as required that the schema omitted.","solutions":["Fix the required key spelling to match an existing property name","Remove the stale required entry if the property no longer exists","Add the missing property to the nested object's properties","Re-run lint to confirm all required keys resolve"],"exampleFix":"// before\nProperty{Required: [\"task_id\"], Properties: {Map: {\"id\": ...}}}\n// after\nProperty{Required: [\"id\"], Properties: {Map: {\"id\": ...}}}","handlingStrategy":"validation","validationCode":"for _, r := range p.Required {\n  if _, ok := p.Properties.Map[r]; !ok {\n    return fmt.Errorf(\"required key %q missing in properties of %q\", r, name)\n  }\n}","typeGuard":"func requiredKeysExist(p *Property) bool {\n  for _, r := range p.Required {\n    if p.Properties == nil {\n      return false\n    }\n    if _, ok := p.Properties.Map[r]; !ok { return false }\n  }\n  return true\n}","tryCatchPattern":null,"preventionTips":["Update the required list whenever renaming or removing properties","Keep required keys scoped to the object that declares them","Re-run the envelope lint after any properties restructure"],"tags":["json-schema","lint","required"],"backgroundTag":"schema-validation-failed","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"}