{"record":{"id":"665c5a469abca5f9","repo":"larksuite/cli","slug":"s-when-must-be-trimmed","errorCode":null,"errorMessage":"%s.When must be trimmed","messagePattern":"(.+?)\\.When must be trimmed","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"shortcuts/common/typed_compiler.go","lineNumber":145,"sourceCode":"\t\trequiredScopes := make(map[string]struct{}, len(auth.RequiredScopes))\n\t\tfor _, scope := range auth.RequiredScopes {\n\t\t\trequiredScopes[scope] = struct{}{}\n\t\t}\n\t\tfor i, conditional := range auth.ConditionalScopes {\n\t\t\tpath := fmt.Sprintf(\"Authorization.%s.ConditionalScopes[%d]\", identity, i)\n\t\t\tif err := validateScopeList(conditional.Scopes, path); err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\t\tif len(conditional.Scopes) == 0 {\n\t\t\t\treturn fmt.Errorf(\"%s.Scopes is empty\", path)\n\t\t\t}\n\t\t\tfor _, scope := range conditional.Scopes {\n\t\t\t\tif _, alwaysRequired := requiredScopes[scope]; alwaysRequired {\n\t\t\t\t\treturn fmt.Errorf(\"%s scope %q is already always required for identity %q\", path, scope, identity)\n\t\t\t\t}\n\t\t\t}\n\t\t\tif conditional.When != strings.TrimSpace(conditional.When) {\n\t\t\t\treturn fmt.Errorf(\"%s.When must be trimmed\", path)\n\t\t\t}\n\t\t\tswitch conditional.Requirement {\n\t\t\tcase typedScopeRequired, typedScopeBestEffort:\n\t\t\tdefault:\n\t\t\t\treturn fmt.Errorf(\"%s.Requirement %q is invalid\", path, conditional.Requirement)\n\t\t\t}\n\t\t}\n\t}\n\tif len(metadata.Authorization.IdentityOrder) > 0 {\n\t\tif len(metadata.Authorization.IdentityOrder) != len(metadata.Authorization.Identities) {\n\t\t\treturn fmt.Errorf(\"Metadata.Authorization.IdentityOrder must contain each declared identity exactly once\")\n\t\t}\n\t\tseen := make(map[typedIdentity]struct{}, len(metadata.Authorization.IdentityOrder))\n\t\tfor _, identity := range metadata.Authorization.IdentityOrder {\n\t\t\tif _, ok := metadata.Authorization.Identities[identity]; !ok {\n\t\t\t\treturn fmt.Errorf(\"Metadata.Authorization.IdentityOrder contains undeclared identity %q\", identity)\n\t\t\t}\n\t\t\tif _, duplicate := seen[identity]; duplicate {","sourceCodeStart":127,"sourceCodeEnd":163,"githubUrl":"https://github.com/larksuite/cli/blob/7fd6ef3c07182257ce776cdc5a614e122d5bd4b3/shortcuts/common/typed_compiler.go#L127-L163","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Trim the When string in the definition literal: When: strings.TrimSpace(expr)","If the value is computed, apply strings.TrimSpace at the point of construction before assigning it to ConditionalScopes[i].When","Re-run compile/startup to confirm the compiler accepts the declaration"],"exampleFix":"// before\nConditionalScopes: []common.TypedConditionalScope{{Scopes: []string{\"im:message\"}, When: \" has_attachment \", Requirement: common.TypedScopeRequired}},\n// after\nConditionalScopes: []common.TypedConditionalScope{{Scopes: []string{\"im:message\"}, When: \"has_attachment\", Requirement: common.TypedScopeRequired}},","handlingStrategy":"validation","validationCode":"func checkWhenTrimmed(when string) bool { return when == strings.TrimSpace(when) }\n// run over each ConditionalScopes entry before compiling","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Always write When literals without surrounding whitespace","Apply strings.TrimSpace at the point where When is computed","Keep condition expressions as named constants reviewed for formatting"],"tags":["go","validation","shortcut-compiler","authorization-scopes"],"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"}