{"record":{"id":"d226213009f2d2cf","repo":"larksuite/cli","slug":"l2-required-key-q-not-found-in-properties","errorCode":null,"errorMessage":"L2: required key %q not found in properties","messagePattern":"L2: required key %q not found in properties","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/schema/lint.go","lineNumber":78,"sourceCode":"\t}\n\n\t// L1: validate every Property type recursively\n\tif env.InputSchema != nil && env.InputSchema.Properties != nil {\n\t\tvalidatePropertyTypes(env.InputSchema.Properties, &errs)\n\t}\n\tif env.OutputSchema != nil && env.OutputSchema.Properties != nil {\n\t\tvalidatePropertyTypes(env.OutputSchema.Properties, &errs)\n\t}\n\n\t// ---- L2: type-level consistency ----\n\tif env.InputSchema != nil && env.InputSchema.Properties != nil {\n\t\t// Walk the whole property tree so format/min-max checks reach leaf\n\t\t// fields nested under the params/data wrapper.\n\t\twalkForL2(env.InputSchema.Properties, &errs)\n\t\t// Top-level required keys must exist in top-level properties.\n\t\tfor _, r := range env.InputSchema.Required {\n\t\t\tif _, ok := env.InputSchema.Properties.Map[r]; !ok {\n\t\t\t\terrs = append(errs, fmt.Errorf(\"L2: required key %q not found in properties\", r))\n\t\t\t}\n\t\t}\n\t}\n\n\t// ---- L3: cross-field self-consistency ----\n\tdangerExpected := env.Meta.Risk == core.RiskWrite || env.Meta.Risk == core.RiskHighRiskWrite\n\tif env.Meta.Danger != dangerExpected {\n\t\terrs = append(errs, fmt.Errorf(\"L3: _meta.danger=%v inconsistent with risk=%q\", env.Meta.Danger, env.Meta.Risk))\n\t}\n\n\t// `yes` lives at inputSchema.properties.yes (sibling of params/data),\n\t// injected only for risk == RiskHighRiskWrite.\n\thasYes := false\n\tif env.InputSchema != nil && env.InputSchema.Properties != nil {\n\t\t_, hasYes = env.InputSchema.Properties.Map[\"yes\"]\n\t}\n\twantYes := env.Meta.Risk == core.RiskHighRiskWrite\n\tif hasYes != wantYes {","sourceCodeStart":60,"sourceCodeEnd":96,"githubUrl":"https://github.com/larksuite/cli/blob/7fd6ef3c07182257ce776cdc5a614e122d5bd4b3/internal/schema/lint.go#L60-L96","documentation":"lintEnvelope's L2 validation enforces that every key listed in inputSchema.required actually exists in inputSchema.properties. This error names the required key that has no corresponding property definition. Top-level required keys must exist in top-level properties, even though format/min-max checks walk the whole property tree.","triggerScenarios":"Linting an envelope where inputSchema.required contains e.g. [\"params\", \"yes\"] but properties only defines {\"params\": ...} — the listed key is missing, misspelled, or only nested deeper in the tree.","commonSituations":"Adding a required flag without defining its property; renaming a property but not the required array; expecting nested keys to satisfy a top-level required entry; forgetting the \"yes\" property for high-risk-write tools.","solutions":["Add a property definition for the missing key in inputSchema.properties.","Fix spelling mismatches between the required array and the properties map.","If the key is genuinely nested, remove it from top-level required and validate it at its actual level.","For RiskHighRiskWrite tools, ensure the \"yes\" property is declared alongside being required."],"exampleFix":"// before\n\"required\": [\"params\", \"confirm\"], \"properties\": { \"params\": {} }\n// after\n\"required\": [\"params\", \"confirm\"], \"properties\": { \"params\": {}, \"confirm\": { \"type\": \"boolean\" } }","handlingStrategy":"validation","validationCode":"func requiredKeysDefined(env map[string]any) []string {\n\ts, _ := env[\"inputSchema\"].(map[string]any)\n\treq, _ := s[\"required\"].([]any)\n\tprops, _ := s[\"properties\"].(map[string]any)\n\tvar missing []string\n\tfor _, r := range req {\n\t\tk, _ := r.(string)\n\t\tif _, ok := props[k]; !ok { missing = append(missing, k) }\n\t}\n\treturn missing\n}","typeGuard":"func allRequiredDefined(schema *InputSchema) bool {\n\tfor _, r := range schema.Required {\n\t\tif _, ok := schema.Properties.Map[r]; !ok { return false }\n\t}\n\treturn true\n}","tryCatchPattern":"errs := lintEnvelope(env)\nfor _, e := range errs {\n\tif strings.Contains(e.Error(), \"required key\") {\n\t\t// add the named key to inputSchema.properties or fix the spelling\n\t}\n}","preventionTips":["Update required[] and properties{} together whenever adding/renaming keys.","Remember top-level required keys must be defined at the top level.","For high-risk-write tools include the \"yes\" property in both arrays/maps."],"tags":["schema","validation","lint"],"backgroundTag":"missing-required-key","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"}