larksuite/cli · error
L2: required key %q not found in properties
Error message
L2: required key %q not found in properties
What it means
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.
Source
Thrown at internal/schema/lint.go:78
}
// L1: validate every Property type recursively
if env.InputSchema != nil && env.InputSchema.Properties != nil {
validatePropertyTypes(env.InputSchema.Properties, &errs)
}
if env.OutputSchema != nil && env.OutputSchema.Properties != nil {
validatePropertyTypes(env.OutputSchema.Properties, &errs)
}
// ---- L2: type-level consistency ----
if env.InputSchema != nil && env.InputSchema.Properties != nil {
// Walk the whole property tree so format/min-max checks reach leaf
// fields nested under the params/data wrapper.
walkForL2(env.InputSchema.Properties, &errs)
// Top-level required keys must exist in top-level properties.
for _, r := range env.InputSchema.Required {
if _, ok := env.InputSchema.Properties.Map[r]; !ok {
errs = append(errs, fmt.Errorf("L2: required key %q not found in properties", r))
}
}
}
// ---- L3: cross-field self-consistency ----
dangerExpected := env.Meta.Risk == core.RiskWrite || env.Meta.Risk == core.RiskHighRiskWrite
if env.Meta.Danger != dangerExpected {
errs = append(errs, fmt.Errorf("L3: _meta.danger=%v inconsistent with risk=%q", env.Meta.Danger, env.Meta.Risk))
}
// `yes` lives at inputSchema.properties.yes (sibling of params/data),
// injected only for risk == RiskHighRiskWrite.
hasYes := false
if env.InputSchema != nil && env.InputSchema.Properties != nil {
_, hasYes = env.InputSchema.Properties.Map["yes"]
}
wantYes := env.Meta.Risk == core.RiskHighRiskWrite
if hasYes != wantYes {View on GitHub (pinned to 7fd6ef3c07)
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.
Example fix
// before
"required": ["params", "confirm"], "properties": { "params": {} }
// after
"required": ["params", "confirm"], "properties": { "params": {}, "confirm": { "type": "boolean" } } Defensive patterns
Strategy: validation
Validate before calling
func requiredKeysDefined(env map[string]any) []string {
s, _ := env["inputSchema"].(map[string]any)
req, _ := s["required"].([]any)
props, _ := s["properties"].(map[string]any)
var missing []string
for _, r := range req {
k, _ := r.(string)
if _, ok := props[k]; !ok { missing = append(missing, k) }
}
return missing
} Type guard
func allRequiredDefined(schema *InputSchema) bool {
for _, r := range schema.Required {
if _, ok := schema.Properties.Map[r]; !ok { return false }
}
return true
} Try / catch
errs := lintEnvelope(env)
for _, e := range errs {
if strings.Contains(e.Error(), "required key") {
// add the named key to inputSchema.properties or fix the spelling
}
} Prevention
- 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.
When it happens
Trigger: 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.
Common situations: 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.
Related errors
- L1: inputSchema.type = %q, want "object"
- L1: outputSchema.type = %q, want "object"
- L1: _meta.envelope_version = %q, want "1.0"
- L3: _meta.danger=%v inconsistent with risk=%q
- expected boolean
AI-assisted analysis of larksuite/cli@7fd6ef3c07 (2026-09-04).
Data as JSON: /api/errors/d226213009f2d2cf.
Report an issue: GitHub.