microsoft/autogen · error · ValueError
Selector function returned an invalid speaker name: {speaker
Error message
Selector function returned an invalid speaker name: {speaker}. Expected one of: {self._participant_names}. What it means
SelectorGroupChatManager raises ValueError when a user-supplied selector_func returns a speaker name that is not in the team's participant names. The selector function bypasses model-based selection, so its return value must exactly match a participant name (or be None to fall through).
Source
Thrown at python/packages/autogen-agentchat/src/autogen_agentchat/teams/_group_chat/_selector_group_chat.py:172
with the selector function as override if it returns a speaker name.
.. note::
This method always returns a single speaker name.
A key assumption is that the agent type is the same as the topic type, which we use as the agent name.
"""
# Use the selector function if provided.
if self._selector_func is not None:
if self._is_selector_func_async:
async_selector_func = cast(AsyncSelectorFunc, self._selector_func)
speaker = await async_selector_func(thread)
else:
sync_selector_func = cast(SyncSelectorFunc, self._selector_func)
speaker = sync_selector_func(thread)
if speaker is not None:
if speaker not in self._participant_names:
raise ValueError(
f"Selector function returned an invalid speaker name: {speaker}. "
f"Expected one of: {self._participant_names}."
)
# Skip the model based selection.
return [speaker]
# Use the candidate function to filter participants if provided
if self._candidate_func is not None:
if self._is_candidate_func_async:
async_candidate_func = cast(AsyncCandidateFunc, self._candidate_func)
participants = await async_candidate_func(thread)
else:
sync_candidate_func = cast(SyncCandidateFunc, self._candidate_func)
participants = sync_candidate_func(thread)
if not participants:
raise ValueError("Candidate function must return a non-empty list of participant names.")
if not all(p in self._participant_names for p in participants):
raise ValueError(View on GitHub (pinned to 027ecf0a37)
Solutions
- Return the exact participant name string (agent.name) from selector_func.
- Return None when you want the manager to fall through to model-based/candidate selection instead of an invalid name.
- Derive names from the participants list rather than hardcoding: return next(p.name for p in participants if <condition>).
Example fix
# before
def selector(thread):
return "assistant" # no participant named 'assistant'
# after
def selector(thread):
if thread and thread[-1].source == "researcher":
return "coder" # exact participant name, or None to skip
return None Defensive patterns
Strategy: validation
Validate before calling
def make_selector(participant_names: list[str]):
def selector(thread):
name = pick_name(thread)
return name if name in participant_names else None
return selector Type guard
def is_valid_speaker(name: str | None, participant_names: Sequence[str]) -> bool:
return name is None or name in participant_names Prevention
- Derive returned names from the participants list, never hardcode strings.
- Return None to fall through to model-based selection instead of guessing.
When it happens
Trigger: selector_func(thread) returns a hardcoded string like "assistant" while the participants are named differently; returning the agent object instead of its .name; case/whitespace mismatch in the returned name.
Common situations: Writing a custom selector_func before finalizing agent names; refactoring agent names without updating the selector; returning '' or a placeholder instead of None to skip selection.
Related errors
- Candidate function must return a non-empty list of participa
- Candidate function returned invalid participant names: {part
- At least two participants are required for SelectorGroupChat
- All agents must have a name.
- All agents must have a unique name.
AI-assisted analysis of microsoft/autogen@027ecf0a37 (2026-08-15).
Data as JSON: /api/errors/45e57c6687231b12.
Report an issue: GitHub.