{"record":{"id":"90bafb9d911bfc3d","repo":"chenhg5/cc-connect","slug":"config-s-users-wildcard-user-ids-appears","errorCode":null,"errorMessage":"config: %s.users: wildcard user_ids=[\"*\"] appears in multiple roles","messagePattern":"config: (.+?)\\.users: wildcard user_ids=\\[\"\\*\"\\] appears in multiple roles","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"config/config.go","lineNumber":1188,"sourceCode":"\tseenUserIDs := make(map[string]string) // userID → role name\n\tfor roleName, rc := range u.Roles {\n\t\tif len(rc.UserIDs) == 0 {\n\t\t\treturn fmt.Errorf(\"config: %s.users.roles.%s has empty user_ids\", prefix, roleName)\n\t\t}\n\t\tfor _, uid := range rc.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(\"config: %s.users: user %q appears in both role %q and %q\", prefix, uid, prev, roleName)\n\t\t\t}\n\t\t\tseenUserIDs[lower] = roleName\n\t\t}\n\t}\n\tif wildcardCount > 1 {\n\t\treturn fmt.Errorf(\"config: %s.users: wildcard user_ids=[\\\"*\\\"] appears in multiple roles\", prefix)\n\t}\n\tif u.DefaultRole != \"\" {\n\t\tif _, ok := u.Roles[u.DefaultRole]; !ok {\n\t\t\treturn fmt.Errorf(\"config: %s.users.default_role %q does not match any defined role\", prefix, u.DefaultRole)\n\t\t}\n\t}\n\treturn nil\n}\n\n// SaveActiveProvider persists the active provider name for a project.\n// It uses surgical text editing to preserve comments and unknown fields.\nfunc SaveActiveProvider(projectName, providerName string) error {\n\tconfigMu.Lock()\n\tdefer configMu.Unlock()\n\treturn patchProjectAgentOption(projectName, \"provider\", providerName)\n}\n\n// SaveProviderModel persists the selected model for a provider in a project.","sourceCodeStart":1170,"sourceCodeEnd":1206,"githubUrl":"https://github.com/chenhg5/cc-connect/blob/4000b2338aa6e850c99df54f8b0ed6ed7460b401/config/config.go#L1170-L1206","documentation":"This error rejects a users config where the wildcard user_id [\"*\"] is defined under more than one role. The wildcard grants everyone, so defining it in multiple roles is redundant and ambiguous about which role applies; the validator fails fast instead.","triggerScenarios":"Running config validation when two or more roles inside a project's users section each contain the wildcard entry user_ids = [\"*\"].","commonSituations":"Setting up 'everyone can chat' defaults and accidentally leaving [\"*\"] in both a default and a restricted role; scaffolding a second role by copying an existing one that already had [\"*\"].","solutions":["Keep the wildcard in exactly one role and delete it from the others","If different classes of users need different roles, list explicit user_ids per role instead of [\"*\"]","Restart/reload the service to re-validate the corrected config"],"exampleFix":"// before\nroles.default.user_ids = [\"*\"]\nroles.admin.user_ids = [\"*\", \"alice\"]\n// after\nroles.default.user_ids = [\"*\"]\nroles.admin.user_ids = [\"alice\"]","handlingStrategy":"validation","validationCode":"wildcards := 0\nfor _, ids := range roles {\n\tfor _, id := range ids {\n\t\tif id == \"*\" { wildcards++ }\n\t}\n}\nif wildcards > 1 { return errors.New(\"wildcard defined in multiple roles\") }","typeGuard":null,"tryCatchPattern":"if err := loadConfig(path); err != nil {\n\tif strings.Contains(err.Error(), \"wildcard\") {\n\t\t// de-duplicate [\"*\"] entries in roles\n\t}\n\treturn err\n}","preventionTips":["Use [\"*\"] in at most one role per users block","Copy role blocks carefully; remove the wildcard when cloning","Add a config linter rule rejecting multiple wildcard entries"],"tags":["config","validation","wildcard"],"backgroundTag":"invalid-config-value","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"}