chenhg5/cc-connect · error

config: .users.roles. 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.

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.

Appendix: 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)