larksuite/cli · critical

Metadata.Service is required

Error message

Metadata.Service is required

What it means

Every typed command must declare Metadata.Service, the service/domain segment used to route and namespace the command. validateCommandMetadata rejects an empty (after trimming whitespace) Service value at compile time. The service is part of the public command identity and help/schema surface.

Source

Thrown at shortcuts/common/typed_compiler.go:91

		for i := range authorization.ConditionalScopes {
			conditional := &authorization.ConditionalScopes[i]
			conditional.Scopes = append([]string(nil), conditional.Scopes...)
			conditional.Params = append([]string(nil), conditional.Params...)
			if conditional.Requirement == "" {
				conditional.Requirement = typedScopeRequired
			}
		}
		identities[identity] = authorization
	}
	metadata.Authorization.Identities = identities
	metadata.Authorization.IdentityOrder = append([]typedIdentity(nil), metadata.Authorization.IdentityOrder...)
	return metadata
}

func validateCommandMetadata(metadata typedCommandMetadata) error {
	service := strings.TrimSpace(string(metadata.Service))
	if service == "" {
		return fmt.Errorf("Metadata.Service is required")
	}
	if service != string(metadata.Service) || strings.ContainsAny(service, " \t\r\n/") {
		return fmt.Errorf("Metadata.Service %q must be one trimmed command segment", metadata.Service)
	}
	command := strings.TrimSpace(metadata.Command)
	if command == "" {
		return fmt.Errorf("Metadata.Command is required")
	}
	if command != metadata.Command || strings.ContainsAny(command, " \t\r\n/") {
		return fmt.Errorf("Metadata.Command %q must be one trimmed command segment", metadata.Command)
	}
	if !strings.HasPrefix(command, "+") {
		return fmt.Errorf("Metadata.Command %q must start with '+'", metadata.Command)
	}
	if command == "+" {
		return fmt.Errorf("Metadata.Command must contain a name after '+'")
	}
	if strings.TrimSpace(metadata.Description) == "" {

View on GitHub (pinned to 7fd6ef3c07)

Solutions

  1. Set Metadata.Service to the owning service/domain segment, e.g. Service: "im" or "docx".
  2. If the value is computed, check why it resolves to empty at definition time.
  3. Trim nothing yourself — the validator trims for the emptiness check, but the raw value must equal its trimmed form (see the sibling segment error).

Example fix

// before
Metadata: common.Metadata{Command: "+send", Description: "Send a message"}
// after
Metadata: common.Metadata{Service: "im", Command: "+send", Description: "Send a message"}
Defensive patterns

Strategy: validation

Validate before calling

if strings.TrimSpace(string(md.Service)) == "" {
  return fmt.Errorf("Metadata.Service must be set")
}

Prevention

When it happens

Trigger: CompileCommandDefinition with typedCommandMetadata{Service: ""} — an unset Service field or a value consisting only of whitespace.

Common situations: Copying a metadata struct and deleting the Service line; constructing metadata programmatically where the service constant failed to resolve; defining a cross-domain utility command and assuming Service is optional.

Understand the failure class

Background: "missing required argument" and "the following required arguments were not provided": what required-argument errors mean and how to fix them — this error's family across 20 libraries.

Related errors


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