{"record":{"id":"a1d4e0ea50648a64","repo":"chenhg5/cc-connect","slug":"default-role-q-does-not-match-any-defined-role","errorCode":null,"errorMessage":"default_role %q does not match any defined role","messagePattern":"default_role %q does not match any defined role","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"core/user_roles.go","lineNumber":233,"sourceCode":"\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()\n\t}\n}\n","sourceCodeStart":215,"sourceCodeEnd":250,"githubUrl":"https://github.com/chenhg5/cc-connect/blob/4000b2338aa6e850c99df54f8b0ed6ed7460b401/core/user_roles.go#L215-L250","documentation":"When default_role is non-empty, ValidateRoleInputs verifies it matches one of the role names defined in the same payload. This ensures every user (including unmatched ones via wildcard or fallback) can be mapped to an existing role. A typo or stale name makes the default unresolvable, so it fails validation.","triggerScenarios":"Calling ValidateRoleInputs with defaultRole set to a name that is not among the RoleInput.Name values, e.g. handleProjectUsers receiving {\"default_role\": \"admins\"} while only a role named \"admin\" is defined.","commonSituations":"Renaming a role in the config but not the default_role field; case/typo mismatches; configs copied between projects where role names differ.","solutions":["Fix default_role to exactly match one of the defined role names (matching is exact here, not case-folded)","Remove default_role (leave empty) if no default is desired","Derive default_role programmatically from roles[0].Name or a constant to avoid drift"],"exampleFix":"// before\nValidateRoleInputs(\"admins\", roles) // roles only define \"admin\"\n// after\nValidateRoleInputs(\"admin\", roles)","handlingStrategy":"validation","validationCode":"names := map[string]bool{}\nfor _, r := range roles { names[r.Name] = true }\nif defaultRole != \"\" && !names[defaultRole] {\n    return fmt.Errorf(\"default_role %q not defined\", defaultRole)\n}\ncore.ValidateRoleInputs(defaultRole, roles)","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Generate default_role from the defined role names rather than hand-typing it","Grep configs after renaming roles to update default_role","Remember matching is exact (case-sensitive) here"],"tags":["validation","roles","config","typo"],"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-14T00:17:10.932Z"}