larksuite/cli · error

.When must be trimmed

Error message

%s.When must be trimmed

What it means

This build-time validation error fires while compiling a typed shortcut command: a ConditionalScopes entry declares a When condition string with leading or trailing whitespace. The compiler requires the condition text to be exactly trimmed so authored declarations are canonical and deterministic.

Solutions

  1. Trim the When string in the definition literal: When: strings.TrimSpace(expr)
  2. If the value is computed, apply strings.TrimSpace at the point of construction before assigning it to ConditionalScopes[i].When
  3. Re-run compile/startup to confirm the compiler accepts the declaration

Example fix

// before
ConditionalScopes: []common.TypedConditionalScope{{Scopes: []string{"im:message"}, When: " has_attachment ", Requirement: common.TypedScopeRequired}},
// after
ConditionalScopes: []common.TypedConditionalScope{{Scopes: []string{"im:message"}, When: "has_attachment", Requirement: common.TypedScopeRequired}},
Defensive patterns

Strategy: validation

Validate before calling

func checkWhenTrimmed(when string) bool { return when == strings.TrimSpace(when) }
// run over each ConditionalScopes entry before compiling

Prevention

When it happens

Trigger: A shortcut definition sets Authorization.Identities[x].ConditionalScopes[i].When to a string like " has_file " (spaces around it); validateCommandMetadata compares When to strings.TrimSpace(When) and fails.

Common situations: Copy-pasting a condition expression from docs or another file and picking up stray spaces; building the When string dynamically with fmt.Sprintf or string concatenation that appends a trailing space; multi-line source strings wrapped across lines.

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/665c5a469abca5f9. Report an issue: GitHub.

Appendix: source

Thrown at shortcuts/common/typed_compiler.go:145

		requiredScopes := make(map[string]struct{}, len(auth.RequiredScopes))
		for _, scope := range auth.RequiredScopes {
			requiredScopes[scope] = struct{}{}
		}
		for i, conditional := range auth.ConditionalScopes {
			path := fmt.Sprintf("Authorization.%s.ConditionalScopes[%d]", identity, i)
			if err := validateScopeList(conditional.Scopes, path); err != nil {
				return err
			}
			if len(conditional.Scopes) == 0 {
				return fmt.Errorf("%s.Scopes is empty", path)
			}
			for _, scope := range conditional.Scopes {
				if _, alwaysRequired := requiredScopes[scope]; alwaysRequired {
					return fmt.Errorf("%s scope %q is already always required for identity %q", path, scope, identity)
				}
			}
			if conditional.When != strings.TrimSpace(conditional.When) {
				return fmt.Errorf("%s.When must be trimmed", path)
			}
			switch conditional.Requirement {
			case typedScopeRequired, typedScopeBestEffort:
			default:
				return fmt.Errorf("%s.Requirement %q is invalid", path, conditional.Requirement)
			}
		}
	}
	if len(metadata.Authorization.IdentityOrder) > 0 {
		if len(metadata.Authorization.IdentityOrder) != len(metadata.Authorization.Identities) {
			return fmt.Errorf("Metadata.Authorization.IdentityOrder must contain each declared identity exactly once")
		}
		seen := make(map[typedIdentity]struct{}, len(metadata.Authorization.IdentityOrder))
		for _, identity := range metadata.Authorization.IdentityOrder {
			if _, ok := metadata.Authorization.Identities[identity]; !ok {
				return fmt.Errorf("Metadata.Authorization.IdentityOrder contains undeclared identity %q", identity)
			}
			if _, duplicate := seen[identity]; duplicate {

View on GitHub (pinned to 7fd6ef3c07)