{"record":{"id":"29f4c3fbf0c092ed","repo":"larksuite/cli","slug":"l1-inputschema-type-q-want-object","errorCode":null,"errorMessage":"L1: inputSchema.type = %q, want \"object\"","messagePattern":"L1: inputSchema\\.type = %q, want \"object\"","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/schema/lint.go","lineNumber":40,"sourceCode":"var validAccessTokens = map[string]bool{\n\t\"user\": true,\n\t\"bot\":  true,\n}\n\n// lintEnvelope runs L1-L3 checks and returns a list of errors. Empty slice\n// means the envelope is compliant.\nfunc lintEnvelope(env Envelope) []error {\n\tvar errs []error\n\n\t// ---- L1: structural ----\n\tif env.Name == \"\" {\n\t\terrs = append(errs, errors.New(\"L1: name must not be empty\"))\n\t}\n\tif env.InputSchema == nil {\n\t\terrs = append(errs, errors.New(\"L1: inputSchema must not be nil\"))\n\t} else {\n\t\tif env.InputSchema.Type != \"object\" {\n\t\t\terrs = append(errs, fmt.Errorf(\"L1: inputSchema.type = %q, want \\\"object\\\"\", env.InputSchema.Type))\n\t\t}\n\t\tif env.InputSchema.Properties == nil {\n\t\t\terrs = append(errs, errors.New(\"L1: inputSchema.properties must not be nil\"))\n\t\t}\n\t}\n\tif env.OutputSchema == nil {\n\t\terrs = append(errs, errors.New(\"L1: outputSchema must not be nil\"))\n\t} else {\n\t\tif env.OutputSchema.Type != \"object\" {\n\t\t\terrs = append(errs, fmt.Errorf(\"L1: outputSchema.type = %q, want \\\"object\\\"\", env.OutputSchema.Type))\n\t\t}\n\t}\n\tif env.Meta == nil {\n\t\terrs = append(errs, errors.New(\"L1: _meta must not be nil\"))\n\t\t// Cannot continue meta-dependent checks\n\t\treturn errs\n\t}\n\tif env.Meta.EnvelopeVersion != \"1.0\" {","sourceCodeStart":22,"sourceCodeEnd":58,"githubUrl":"https://github.com/larksuite/cli/blob/7fd6ef3c07182257ce776cdc5a614e122d5bd4b3/internal/schema/lint.go#L22-L58","documentation":"lintEnvelope performs L1 structural validation of tool envelopes. Every tool must declare inputSchema with type exactly \"object\"; this error is appended when the declared type is anything else (or empty). This keeps all tool inputs as JSON objects, which the generic service machinery relies on.","triggerScenarios":"Running the schema lint (TestLintEnvelope_Valid, TestAllEnvelopesPass, or envelope-lint tooling) on an envelope whose inputSchema.type is e.g. \"string\", \"array\", or omitted/mistyped.","commonSituations":"Hand-writing a new tool envelope and copying a parameter-level schema to the top level; forgetting the params/data wrapper object; a generator emitting a non-object root schema.","solutions":["Set inputSchema.type to \"object\" and place the actual parameters under inputSchema.properties (e.g. a params/data wrapper).","Move non-object schema (string/array) down into a property's schema instead of the root.","Re-run the lint after the fix to confirm no remaining L1 errors."],"exampleFix":"// before\n\"inputSchema\": { \"type\": \"string\" }\n// after\n\"inputSchema\": { \"type\": \"object\", \"properties\": { \"params\": { \"type\": \"string\" } } }","handlingStrategy":"validation","validationCode":"func inputSchemaIsObject(env map[string]any) bool {\n\ts, ok := env[\"inputSchema\"].(map[string]any)\n\treturn ok && s[\"type\"] == \"object\"\n}","typeGuard":"func hasObjectInputSchema(env *Envelope) bool { return env.InputSchema != nil && env.InputSchema.Type == \"object\" }","tryCatchPattern":"errs := lintEnvelope(env)\nfor _, e := range errs {\n\tif strings.Contains(e.Error(), \"inputSchema.type\") {\n\t\t// fix envelope: set type \"object\" and nest params under properties\n\t}\n}","preventionTips":["Start every tool envelope from a template with type \"object\" at the root.","Nest parameter schemas under properties, never at the root level.","Run the envelope lint in CI before publishing tool metadata."],"tags":["schema","validation","lint"],"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"}