chenhg5/cc-connect · error

config: %s.users.roles.%s has empty user_ids

Error message

config: %s.users.roles.%s has empty user_ids

What it means

CC-Connect requires every role under `[projects.users.roles]` to list at least one user ID. If a role's `user_ids` array is empty or missing, validateUsersConfig rejects the config, naming the project prefix and role name. This catches roles that would never match any user.

Source

Thrown at config/config.go:1173

	if _, ok := supportedReferenceEnclosureStyles[strings.ToLower(strings.TrimSpace(rc.EnclosureStyle))]; !ok {
		return fmt.Errorf("config: %s.references.enclosure_style has unsupported value %q", prefix, rc.EnclosureStyle)
	}
	return nil
}

// validateUsersConfig checks the [projects.users] section for consistency.
func validateUsersConfig(prefix string, u *UsersConfig) error {
	if u == nil {
		return nil
	}
	if len(u.Roles) == 0 {
		return fmt.Errorf("config: %s.users has no roles defined", prefix)
	}
	wildcardCount := 0
	seenUserIDs := make(map[string]string) // userID → role name
	for roleName, rc := range u.Roles {
		if len(rc.UserIDs) == 0 {
			return fmt.Errorf("config: %s.users.roles.%s has empty user_ids", prefix, roleName)
		}
		for _, uid := range rc.UserIDs {
			if uid == "*" {
				wildcardCount++
				continue
			}
			lower := strings.ToLower(uid)
			if prev, dup := seenUserIDs[lower]; dup {
				return fmt.Errorf("config: %s.users: user %q appears in both role %q and %q", prefix, uid, prev, roleName)
			}
			seenUserIDs[lower] = roleName
		}
	}
	if wildcardCount > 1 {
		return fmt.Errorf("config: %s.users: wildcard user_ids=[\"*\"] appears in multiple roles", prefix)
	}
	if u.DefaultRole != "" {
		if _, ok := u.Roles[u.DefaultRole]; !ok {

View on GitHub (pinned to 4000b2338a)

Solutions

  1. Add at least one user ID to the role's user_ids array
  2. Use "*" in user_ids to match all users if the role should be a catch-all
  3. Delete the empty role block if it's no longer needed

Example fix

# before
[projects.myapp.users.roles.admins]
user_ids = []

# after
[projects.myapp.users.roles.admins]
user_ids = ["ou_1234", "ou_5678"]
Defensive patterns

Strategy: validation

Validate before calling

for name, role := range cfg.Projects[i].Users.Roles {
    if len(role.UserIDs) == 0 {
        return fmt.Errorf("role %q has empty user_ids", name)
    }
}

Type guard

func roleHasMembers(rc RoleConfig) bool { return len(rc.UserIDs) > 0 }

Prevention

When it happens

Trigger: Loading config.toml where a role table declares no user_ids, e.g. `[projects.myapp.users.roles.admins]` with `user_ids = []` or the key omitted entirely.

Common situations: Adding a role as a stub before assigning members; a role whose members were all removed; renaming a role but leaving the old empty block behind.

Understand the failure class

Background: "must not be empty", "cannot be empty" — required-field validation errors across open-source libraries — this error's family across 41 libraries.

Related errors


AI-assisted analysis of chenhg5/cc-connect@4000b2338a (2026-09-06). Data as JSON: /api/errors/2c3b5453b742d0a6. Report an issue: GitHub.