{"record":{"id":"c467def2fa6c145c","repo":"chenhg5/cc-connect","slug":"wildcard-user-ids-appears-in-multiple-roles","errorCode":null,"errorMessage":"wildcard user_ids=[\"*\"] appears in multiple roles","messagePattern":"wildcard user_ids=\\[\"\\*\"\\] appears in multiple roles","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"core/user_roles.go","lineNumber":229,"sourceCode":"\tfor _, ri := range roles {\n\t\troleNames[ri.Name] = true\n\t\tif len(ri.UserIDs) == 0 {\n\t\t\treturn fmt.Errorf(\"role %q has empty user_ids\", ri.Name)\n\t\t}\n\t\tfor _, uid := range ri.UserIDs {\n\t\t\tif uid == \"*\" {\n\t\t\t\twildcardCount++\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tlower := strings.ToLower(uid)\n\t\t\tif prev, dup := seenUserIDs[lower]; dup {\n\t\t\t\treturn fmt.Errorf(\"user %q appears in both role %q and %q\", uid, prev, ri.Name)\n\t\t\t}\n\t\t\tseenUserIDs[lower] = ri.Name\n\t\t}\n\t}\n\tif wildcardCount > 1 {\n\t\treturn fmt.Errorf(\"wildcard user_ids=[\\\"*\\\"] appears in multiple roles\")\n\t}\n\tif defaultRole != \"\" {\n\t\tif !roleNames[defaultRole] {\n\t\t\treturn fmt.Errorf(\"default_role %q does not match any defined role\", defaultRole)\n\t\t}\n\t}\n\treturn nil\n}\n\n// Stop terminates all per-role rate limiter goroutines. Nil-receiver safe.\nfunc (m *UserRoleManager) Stop() {\n\tif m == nil {\n\t\treturn\n\t}\n\tm.mu.Lock()\n\tdefer m.mu.Unlock()\n\tfor _, rl := range m.limiters {\n\t\trl.Stop()","sourceCodeStart":211,"sourceCodeEnd":247,"githubUrl":"https://github.com/chenhg5/cc-connect/blob/4000b2338aa6e850c99df54f8b0ed6ed7460b401/core/user_roles.go#L211-L247","documentation":"ValidateRoleInputs allows the wildcard user_ids=[\"*\"] in only one role, because a wildcard matches every user and two wildcards would make role resolution ambiguous. It counts wildcard occurrences and rejects the config when more than one role contains \"*\".","triggerScenarios":"Calling ValidateRoleInputs where two or more RoleInput entries include the literal \"*\" in their UserIDs slice.","commonSituations":"A config that defines a catch-all 'everyone' role plus a second role that also used \"*\" as a shortcut for 'any user with this role'; templated configs where the wildcard was duplicated across role blocks.","solutions":["Keep \"*\" in exactly one role (usually the lowest-privilege fallback) and list concrete user IDs in the others","Merge the two wildcard roles into one","If the intent is tiered defaults, model that with role ordering/priority instead of multiple wildcards"],"exampleFix":"// before\nroles := []core.RoleInput{\n    {Name: \"admin\", UserIDs: []string{\"*\"}},\n    {Name: \"dev\", UserIDs: []string{\"*\"}},\n}\n// after\nroles := []core.RoleInput{\n    {Name: \"admin\", UserIDs: []string{\"alice\"}},\n    {Name: \"dev\", UserIDs: []string{\"*\"}},\n}","handlingStrategy":"validation","validationCode":"wildcards := 0\nfor _, r := range roles {\n    for _, u := range r.UserIDs {\n        if u == \"*\" { wildcards++ }\n    }\n}\nif wildcards > 1 {\n    return errors.New(\"only one role may use wildcard user_ids\")\n}\ncore.ValidateRoleInputs(defaultRole, roles)","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Use \"*\" only in a single fallback role","Review templated configs for duplicated wildcard entries","Model role priority explicitly instead of multiple catch-alls"],"tags":["validation","roles","wildcard","ambiguous"],"backgroundTag":"conflicting-config-options","analyzedSha":"4000b2338aa6e850c99df54f8b0ed6ed7460b401","analyzedAt":"2026-09-06T11:45:09.575Z","contentChangedAt":"2026-09-06T11:45:09.575Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}