{"record":{"id":"d1827b9c12c00fb4","repo":"larksuite/cli","slug":"metadata-authorization-identityorder-contains-dupl","errorCode":null,"errorMessage":"Metadata.Authorization.IdentityOrder contains duplicate identity %q","messagePattern":"Metadata\\.Authorization\\.IdentityOrder contains duplicate identity %q","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"shortcuts/common/typed_compiler.go","lineNumber":164,"sourceCode":"\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 {\n\t\t\t\treturn fmt.Errorf(\"Metadata.Authorization.IdentityOrder contains duplicate identity %q\", identity)\n\t\t\t}\n\t\t\tseen[identity] = struct{}{}\n\t\t}\n\t}\n\treturn nil\n}\n\nfunc validateScopeList(scopes []string, path string) error {\n\tseen := make(map[string]struct{}, len(scopes))\n\tfor i, scope := range scopes {\n\t\tif strings.TrimSpace(scope) == \"\" || scope != strings.TrimSpace(scope) {\n\t\t\treturn fmt.Errorf(\"%s[%d] must be a non-blank trimmed scope\", path, i)\n\t\t}\n\t\tif _, ok := seen[scope]; ok {\n\t\t\treturn fmt.Errorf(\"%s contains duplicate scope %q\", path, scope)\n\t\t}\n\t\tseen[scope] = struct{}{}\n\t}","sourceCodeStart":146,"sourceCodeEnd":182,"githubUrl":"https://github.com/larksuite/cli/blob/7fd6ef3c07182257ce776cdc5a614e122d5bd4b3/shortcuts/common/typed_compiler.go#L146-L182","documentation":"Compile-time guard in validateCommandMetadata: IdentityOrder lists the same identity more than once; each declared identity must appear exactly once.","triggerScenarios":"IdentityOrder lists the same identity twice, e.g. {user, user} for a two-identity command, or a duplicate introduced by an append during programmatic construction.","commonSituations":"Merging two identity-order slices without deduplicating; copy-paste duplication inside a literal; generating the order with code that appends defaults then explicit entries.","solutions":["Deduplicate IdentityOrder so each declared identity appears once","If constructing programmatically, build from the Identities map keys and use a set to avoid repeats","Consider deriving the order directly from map keys if ordering does not matter"],"exampleFix":"// before\nIdentityOrder: []common.TypedIdentity{common.TypedIdentityUser, common.TypedIdentityUser, common.TypedIdentityBot},\n// after\nIdentityOrder: []common.TypedIdentity{common.TypedIdentityUser, common.TypedIdentityBot},","handlingStrategy":"validation","validationCode":"seen := map[common.TypedIdentity]bool{}\nfor _, id := range meta.Authorization.IdentityOrder { if seen[id] { return fmt.Errorf(\"duplicate identity %q\", id) }; seen[id] = true }","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Deduplicate before assignment when building the slice programmatically","Write order literals one entry per identity and review against Identities keys","Prefer generating the order from a single identities slice"],"tags":["go","validation","shortcut-compiler","authorization"],"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"}