{"record":{"id":"e61ba30ee913aff8","repo":"larksuite/cli","slug":"l3-meta-danger-v-inconsistent-with-risk-q","errorCode":null,"errorMessage":"L3: _meta.danger=%v inconsistent with risk=%q","messagePattern":"L3: _meta\\.danger=(.+?) inconsistent with risk=%q","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/schema/lint.go","lineNumber":86,"sourceCode":"\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 {\n\t\terrs = append(errs, fmt.Errorf(\"L3: inputSchema `yes` property=%v inconsistent with risk=%q\", hasYes, env.Meta.Risk))\n\t}\n\n\tif len(env.Meta.AccessTokens) == 0 {\n\t\terrs = append(errs, errors.New(\"L3: _meta.access_tokens must not be empty\"))\n\t}\n\tfor _, t := range env.Meta.AccessTokens {\n\t\tif !validAccessTokens[t] {","sourceCodeStart":68,"sourceCodeEnd":104,"githubUrl":"https://github.com/larksuite/cli/blob/7fd6ef3c07182257ce776cdc5a614e122d5bd4b3/internal/schema/lint.go#L68-L104","documentation":"lintEnvelope's L3 cross-field consistency check requires _meta.danger to equal (risk == write || risk == high_risk_write). This error is thrown when danger disagrees with the declared risk level — danger true with a non-write risk, or danger false with a write/high-risk-write risk.","triggerScenarios":"Linting an envelope where _meta.risk is e.g. \"read\" but _meta.danger is true, or risk is \"write\"/\"high_risk_write\" while danger is false.","commonSituations":"Changing a tool's risk level after the fact without updating danger; copying _meta from another tool; adding the yes confirmation schema for high_risk_write but forgetting to set danger=true, or vice versa.","solutions":["Set _meta.danger = true when risk is write or high_risk_write, false otherwise.","If the tool is not really mutating, downgrade risk instead of forcing danger.","Re-run the lint to confirm L3 cross-field consistency and that yes-property presence matches high_risk_write."],"exampleFix":"// before\n\"_meta\": { \"risk\": \"read\", \"danger\": true }\n// after\n\"_meta\": { \"risk\": \"read\", \"danger\": false }","handlingStrategy":"validation","validationCode":"func dangerMatchesRisk(meta map[string]any) bool {\n\trisk, _ := meta[\"risk\"].(string)\n\tdanger, _ := meta[\"danger\"].(bool)\n\treturn danger == (risk == \"write\" || risk == \"high_risk_write\")\n}","typeGuard":"func dangerConsistent(meta *Meta) bool { return meta.Danger == (meta.Risk == core.RiskWrite || meta.Risk == core.RiskHighRiskWrite) }","tryCatchPattern":"errs := lintEnvelope(env)\nfor _, e := range errs {\n\tif strings.Contains(e.Error(), \"_meta.danger\") {\n\t\t// align danger with risk: true for write/high_risk_write, else false\n\t}\n}","preventionTips":["Derive danger from risk in generators instead of hand-setting both.","Update danger whenever a tool's risk classification changes.","Run the envelope lint in CI to catch cross-field drift before release."],"tags":["schema","validation","lint","metadata"],"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"}