larksuite/cli · error

L1: inputSchema.type = %q, want "object"

Error message

L1: inputSchema.type = %q, want "object"

What it means

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.

Source

Thrown at internal/schema/lint.go:40

var validAccessTokens = map[string]bool{
	"user": true,
	"bot":  true,
}

// lintEnvelope runs L1-L3 checks and returns a list of errors. Empty slice
// means the envelope is compliant.
func lintEnvelope(env Envelope) []error {
	var errs []error

	// ---- L1: structural ----
	if env.Name == "" {
		errs = append(errs, errors.New("L1: name must not be empty"))
	}
	if env.InputSchema == nil {
		errs = append(errs, errors.New("L1: inputSchema must not be nil"))
	} else {
		if env.InputSchema.Type != "object" {
			errs = append(errs, fmt.Errorf("L1: inputSchema.type = %q, want \"object\"", env.InputSchema.Type))
		}
		if env.InputSchema.Properties == nil {
			errs = append(errs, errors.New("L1: inputSchema.properties must not be nil"))
		}
	}
	if env.OutputSchema == nil {
		errs = append(errs, errors.New("L1: outputSchema must not be nil"))
	} else {
		if env.OutputSchema.Type != "object" {
			errs = append(errs, fmt.Errorf("L1: outputSchema.type = %q, want \"object\"", env.OutputSchema.Type))
		}
	}
	if env.Meta == nil {
		errs = append(errs, errors.New("L1: _meta must not be nil"))
		// Cannot continue meta-dependent checks
		return errs
	}
	if env.Meta.EnvelopeVersion != "1.0" {

View on GitHub (pinned to 7fd6ef3c07)

Solutions

  1. Set inputSchema.type to "object" and place the actual parameters under inputSchema.properties (e.g. a params/data wrapper).
  2. Move non-object schema (string/array) down into a property's schema instead of the root.
  3. Re-run the lint after the fix to confirm no remaining L1 errors.

Example fix

// before
"inputSchema": { "type": "string" }
// after
"inputSchema": { "type": "object", "properties": { "params": { "type": "string" } } }
Defensive patterns

Strategy: validation

Validate before calling

func inputSchemaIsObject(env map[string]any) bool {
	s, ok := env["inputSchema"].(map[string]any)
	return ok && s["type"] == "object"
}

Type guard

func hasObjectInputSchema(env *Envelope) bool { return env.InputSchema != nil && env.InputSchema.Type == "object" }

Try / catch

errs := lintEnvelope(env)
for _, e := range errs {
	if strings.Contains(e.Error(), "inputSchema.type") {
		// fix envelope: set type "object" and nest params under properties
	}
}

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Understand the failure class

Background: Schema validation failed / invalid input schema: payload rejected because its shape doesn't match the expected schema — this error's family across 28 libraries.

Related errors


AI-assisted analysis of larksuite/cli@7fd6ef3c07 (2026-09-04). Data as JSON: /api/errors/29f4c3fbf0c092ed. Report an issue: GitHub.