Skip to content
Back to skills

2367 Group Agent Loading Fix B0f74e16

ASecurity

**Fix Title:** Group Agents Not Loading in Per-User Semantic Kernel Mode **Issue Description:** Group agents were not being loaded when per-user semantic kernel mode was enabled, causing group agents to fall back to global agents and resulting in zero plugins/actions available. **Root Cause:** The `load_user_semantic_kernel()` function only loaded personal agents and global agents (when merge enabled), but completely omitted group agents from the user's active group. **Fixed/Implemented in

  • 9 stars
  • 0 votes
  • 0 copies
  • 0 views
  • Added October 11, 2026
testingpythondebuggingdatabasesecurity

Security analysis

A100/100

Scanned October 11, 2026

npx -y skills add tools-only/X-Skills --skill 2367-group_agent_loading_fix_b0f74e16 --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of 2367 Group Agent Loading Fix B0f74e16?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for 2367 Group Agent Loading Fix B0f74e16
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/tools-only-2367-group-agent-loading-fix-b0f74e16/badge)](https://www.skillsdirectory.com/skills/tools-only-2367-group-agent-loading-fix-b0f74e16)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

SKILL.md
# Group Agent Loading Fix

## Header Information

**Fix Title:** Group Agents Not Loading in Per-User Semantic Kernel Mode  
**Issue Description:** Group agents were not being loaded when per-user semantic kernel mode was enabled, causing group agents to fall back to global agents and resulting in zero plugins/actions available.  
**Root Cause:** The `load_user_semantic_kernel()` function only loaded personal agents and global agents (when merge enabled), but completely omitted group agents from the user's active group.  
**Fixed/Implemented in version:** **0.237.008** (matches `config.py` `app.config['VERSION']`)  
**Date:** January 31, 2026  

## Problem Statement

### Symptoms
When a user selected a group agent in per-user semantic kernel mode:
- The agent selection would fall back to the global "researcher" agent
- Plugin count would be zero (`plugin_count: 0, plugins: []`)
- Agent would ask clarifying questions instead of executing available actions
- No group agents appeared in the available agents list
- Group actions (plugins) were not accessible even though they existed in the database

### Impact
- **Severity:** High - Group agents completely non-functional in per-user kernel mode
- **Affected Users:** All users with per-user semantic kernel enabled who are members of groups
- **Workaround:** None - only global agents worked

### Evidence from Logs
```
[SK Loader] User settings found 1 agents for user 'f016493e-9395-4120-91b5-bac4276b6b6c'
[SK Loader] Found 2 global agents to merge
[SK Loader] After merging: 3 total agents
[DEBUG] [INFO]: [SK Loader] Merged agents: [('researcher', True), ('servicenow_test_agent', True), ('researcher', False)]
[DEBUG] [INFO]: [SK Loader] Looking for agent named 'cio6_servicenow_test_agent' with is_global=False
[DEBUG] [INFO]: [SK Loader] User NO agent found matching user-selected agent: cio6_servicenow_test_agent
[SK Loader] User f016493e-9395-4120-91b5-bac4276b6b6c No agent found matching user-selected agent: cio6_servicenow_test_agent
```

Notice: Only 3 agents loaded (2 global + 1 personal), **zero group agents** despite user being member of group "cio6".

## Root Cause Analysis

### Architectural Gap
The `load_user_semantic_kernel()` function in `semantic_kernel_loader.py` had the following loading sequence:

1. ✅ Load personal agents via `get_personal_agents(user_id)`
2. ✅ Conditionally merge global agents if `merge_global_semantic_kernel_with_workspace` enabled
3. ❌ **MISSING:** Load group agents from user's active group
4. ✅ Load personal actions via `get_personal_actions(user_id)`
5. ✅ Conditionally merge global actions if merge enabled

### Why It Was Missed
The code did not load group agents from the user's active group in per-user semantic kernel mode. This meant:
- Group agents were never available for selection
- Users in groups could not use group-level agent configurations
- The system would fall back to global or personal agents even when a group agent was requested

**Note:** Group actions (plugins) are loaded separately by the agent itself based on the selected agent's configuration, not in the `load_user_semantic_kernel()` function. This fix specifically addresses group agent loading.

## Technical Details

### Files Modified
1. **`semantic_kernel_loader.py`** (Lines ~1180-1280)
   - Changed import from `get_user_groups` to `require_active_group`
   - Added group agent loading from active group only
   - Added security validation to ensure selected group agents match the user's active group
   - Simplified error handling for cases where no active group is selected

2. **`config.py`**
   - Updated VERSION to "0.237.008"

### Code Changes

#### Before (Pseudocode)
```python
agents_cfg = get_personal_agents(user_id)
# Mark personal agents
for agent in agents_cfg:
    agent['is_global'] = False

# No group agent loading at all
    
# Merge global agents if enabled
if merge_global:
    # Add global agents

# Load personal actions only
plugin_manifests = get_personal_actions(user_id)

# No group action loading at all
```

#### After (Pseudocode)
```python
agents_cfg = get_personal_agents(user_id)
# Mark personal agents
for agent in agents_cfg:
    agent['is_global'] = False

# Load group agents from active group only
try:
    active_group_id = require_active_group(user_id)
    group_agents = get_group_agents(active_group_id)
    for group_agent in group_agents:
        group_agent['is_global'] = False
        group_agent['is_group'] = True
        group_agent['group_id'] = active_group_id
        agents_cfg.append(group_agent)
except ValueError:
    # No active group - normal case
    pass

# Security check: If a group agent is selected, validate it matches active group
if selected_agent_is_group:
    resolved_group_id = selected_agent_data.get('group_id')
    active_group_id = require_active_group(user_id)
    if resolved_group_id != active_group_id:
        # Reject - security violation
        load_core_plugins_only(kernel, settings)
        return kernel, None

# Merge global agents if enabled (unchanged)
if merge_global:
    # Add global agents

# Load personal actions
plugin_manifests = get_personal_actions(user_id)
```

### Key Implementation Details

**Group Agent Loading:**
```python
from functions_group import require_active_group
from functions_group_agents import get_group_agents

# Load group agents for user's active group (if any)
try:
    active_group_id = require_active_group(user_id)
    group_agents = get_group_agents(active_group_id)
    if group_agents:
        print(f"[SK Loader] Found {len(group_agents)} group agents for active group '{active_group_id}'")
        # Badge group agents with group metadata
        for group_agent in group_agents:
            group_agent['is_global'] = False
            group_agent['is_group'] = True
        agents_cfg.extend(group_agents)
        print(f"[SK Loader] After merging group agents: {len(agents_cfg)} total agents")
    else:
        print(f"[SK Loader] No group agents found for active group '{active_group_id}'")
except ValueError:
    # No active group set - this is fine, just means no group agents available
    print(f"[SK Loader] User '{user_id}' has no active group - skipping group agent loading")
```

**Security Validation for Selected Group Agents:**
```python
# Append selected group agent (if any) to the candidate list so downstream selection logic can resolve it
selected_agent_data = selected_agent if isinstance(selected_agent, dict) else {}
selected_agent_is_group = selected_agent_data.get('is_group', False)
if selected_agent_is_group:
    resolved_group_id = selected_agent_data.get('group_id')
    active_group_id = None
    
    # Group agent MUST have a group_id
    if not resolved_group_id:
        log_event(
            "[SK Loader] Group agent selected but no group_id provided in selection data.",
            level=logging.ERROR
        )
        load_core_plugins_only(kernel, settings)
        return kernel, None
    
    try:
        active_group_id = require_active_group(user_id)
        if resolved_group_id != active_group_id:
            debug_print(
                f"[SK Loader] Selected group agent references group {resolved_group_id}, active group is {active_group_id}."
            )
            log_event(
                "[SK Loader] Group agent selected from the non-active group.",
                level=logging.ERROR
            )
            load_core_plugins_only(kernel, settings)
            return kernel, None
    except ValueError as err:
        debug_print(f"[SK Loader] No active group available while loading group agent: {err}")
        log_event(
            "[SK Loader] Group agent selected but no active group in settings.",
            level=logging.ERROR
        )
        load_core_plugins_only(kernel, settings)
        return kernel, None
```

### Functions Used
- **`require_active_group(user_id)`** - Returns the active group ID or raises ValueError if none selected (from `functions_group.py`)
- **`get_group_agents(group_id)`** - Returns all agents for a specific group (from `functions_group_agents.py`)
- **`get_group_agent(group_id, agent_identifier)`** - Returns a specific agent from a group by ID or name (from `functions_group_agents.py`)

### Error Handling and Security
- Group agent loading wrapped in try-except with ValueError handling for no active group (normal case)
- Security validation ensures selected group agents match the user's active group
- If a user attempts to select a group agent from a non-active group, the system loads core plugins only and returns None
- All errors logged with descriptive messages for debugging
- System gracefully degrades to personal + global agents if group loading fails

## Validation

### Test Scenario
1. **Setup:**
   - User `f016493e-9395-4120-91b5-bac4276b6b6c` has active group `cio6` (ID: `72254e24-4bc6-4680-bc2e-c56d5214d8e8`)
   - Group has agent `cio6_servicenow_test_agent` with action `cio6_servicenow_query_incidents`
   - Per-user semantic kernel mode enabled
   - Global agent merging enabled

2. **User Action:**
   - User selects group agent `cio6_servicenow_test_agent`
   - User submits message: "Show me all ServiceNow incidents"

### Before Fix - Failure Behavior
```
[SK Loader] User settings found 1 agents for user 'f016493e-9395-4120-91b5-bac4276b6b6c'
[SK Loader] After merging: 3 total agents  # Only personal + global
[SK Loader] Looking for agent named 'cio6_servicenow_test_agent' with is_global=False
[SK Loader] User NO agent found matching user-selected agent: cio6_servicenow_test_agent
[SK Loader] selected_agent fallback to first agent: researcher  # ❌ Wrong agent
[Enhanced Agent Citations] Extracted 0 detailed plugin invocations  # ❌ No actions
{'agent': 'researcher', 'plugin_count': 0}  # ❌ Zero plugins
```

**Result:** Agent asks clarifying questions instead of querying ServiceNow.

### After Fix - Success Behavior
```
[SK Loader] User settings found 1 agents for user 'f016493e-9395-4120-91b5-bac4276b6b6c'
[SK Loader] Found 1 group agents for active group '72254e24-4bc6-4680-bc2e-c56d5214d8e8'  # ✅ Group agent loaded
[SK Loader] After merging group agents: 2 total agents  # ✅ Personal + Group
[SK Loader] After merging: 4 total agents  # ✅ Includes global agents
[SK Loader] Merged agents: [('researcher', True), ('servicenow_test_agent', True), ('researcher', False), ('cio6_servicenow_test_agent', False)]  # ✅ Group agent present
[SK Loader] User f016493e-9395-4120-91b5-bac4276b6b6c Found EXACT match for agent: cio6_servicenow_test_agent (is_global=False)  # ✅ Agent found
[SK Loader] Plugin cio6_servicenow_query_incidents: SUCCESS  # ✅ Plugin loaded
```

**Result:** Correct group agent selected with its actions available for execution.

### Verification Checklist
- [x] Personal agents still load correctly
- [x] Global agents still merge correctly when enabled
- [x] Group agents load from active group when one is selected
- [x] No errors when user has no active group selected
- [x] Agents properly marked with `is_group` and `group_id` flags
- [x] Agent selection finds group agents by name
- [x] Security validation prevents users from accessing agents outside their active group
- [x] Error handling prevents crashes if group loading fails
- [x] Logging provides visibility into group loading process

## Security Enhancement

This fix includes a critical security validation that was added as part of the implementation:

**Security Check:** When a user selects a group agent, the system now validates that the agent's `group_id` matches the user's currently active group. This prevents users from potentially accessing group agents from groups they are members of but have not set as active, ensuring proper access control.

**Implementation:** If a mismatch is detected between the selected agent's group and the user's active group, the system:
1. Logs an error with details about the mismatch
2. Loads only core plugins (no sensitive group-specific plugins)
3. Returns None for the agent, preventing unauthorized access

This security layer ensures that group agent access is strictly controlled through the active group mechanism.

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…

Newsletter

Get the weekly list of safe new skills, and the ones we pulled.