{"record":{"id":"84a51b1b67226d03","repo":"larksuite/cli","slug":"l1-outputschema-type-q-want-object","errorCode":null,"errorMessage":"L1: outputSchema.type = %q, want \"object\"","messagePattern":"L1: outputSchema\\.type = %q, want \"object\"","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/schema/lint.go","lineNumber":50,"sourceCode":"\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\" {\n\t\terrs = append(errs, fmt.Errorf(\"L1: _meta.envelope_version = %q, want \\\"1.0\\\"\", env.Meta.EnvelopeVersion))\n\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}","sourceCodeStart":32,"sourceCodeEnd":68,"githubUrl":"https://github.com/larksuite/cli/blob/7fd6ef3c07182257ce776cdc5a614e122d5bd4b3/internal/schema/lint.go#L32-L68","documentation":"lintEnvelope's L1 check requires outputSchema, when present, to declare type exactly \"object\". The error is appended when an envelope declares a non-object output schema. This normalizes all tool outputs to JSON objects for downstream consumers.","triggerScenarios":"Linting an envelope whose outputSchema.type is e.g. \"string\", \"array\", or a typo like \"objec\" instead of \"object\".","commonSituations":"Describing a tool that returns a list and using array as the root type instead of wrapping it in an object; hand-editing schema JSON and mistyping the type; a generator producing bare scalar output schemas.","solutions":["Set outputSchema.type to \"object\" and nest the actual payload under properties (e.g. a data wrapper).","Fix typos in the type value (\"objec\" -> \"object\").","Re-run the lint to confirm the envelope passes L1."],"exampleFix":"// before\n\"outputSchema\": { \"type\": \"array\" }\n// after\n\"outputSchema\": { \"type\": \"object\", \"properties\": { \"data\": { \"type\": \"array\" } } }","handlingStrategy":"validation","validationCode":"func outputSchemaIsObject(env map[string]any) bool {\n\ts, ok := env[\"outputSchema\"].(map[string]any)\n\treturn ok && s[\"type\"] == \"object\"\n}","typeGuard":"func hasObjectOutputSchema(env *Envelope) bool { return env.OutputSchema != nil && env.OutputSchema.Type == \"object\" }","tryCatchPattern":"errs := lintEnvelope(env)\nfor _, e := range errs {\n\tif strings.Contains(e.Error(), \"outputSchema.type\") {\n\t\t// fix envelope: set type \"object\" and wrap payloads in a data property\n\t}\n}","preventionTips":["Wrap list/scalar outputs in an object with a data property.","Copy type values from a validated template to avoid typos.","Run the envelope lint before merging envelope changes."],"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"}