microsoft/autogen · error · ValueError
Candidate function returned invalid participant names: {part
Error message
Candidate function returned invalid participant names: {participants}. Expected one of: {self._participant_names}. What it means
SelectorGroupChatManager raises ValueError when candidate_func returns names that are not all members of the team's participant names. Like selector_func, the candidate function operates on name strings that must exactly match registered participants.
Source
Thrown at python/packages/autogen-agentchat/src/autogen_agentchat/teams/_group_chat/_selector_group_chat.py:190
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(
f"Candidate function returned invalid participant names: {participants}. "
f"Expected one of: {self._participant_names}."
)
else:
# Construct the candidate agent list to be selected from, skip the previous speaker if not allowed.
if self._previous_speaker is not None and not self._allow_repeated_speaker:
participants = [p for p in self._participant_names if p != self._previous_speaker]
else:
participants = list(self._participant_names)
assert len(participants) > 0
# Construct agent roles.
# Each agent sould appear on a single line.
roles = ""
for topic_type, description in zip(self._participant_names, self._participant_descriptions, strict=True):
roles += re.sub(r"\s+", " ", f"{topic_type}: {description}").strip() + "\n"
roles = roles.strip()View on GitHub (pinned to 027ecf0a37)
Solutions
- Intersect returned names with the real participant set: [n for n in result if n in participant_names] and ensure the result is non-empty.
- Derive candidate names from the same agents passed to SelectorGroupChat, not from a separate constant.
- Add an assert all(n in participant_names for n in result) inside your candidate function during development.
Example fix
# before
CANDIDATES = ["writer", "critic"] # stale; team has 'coder' not 'writer'
def candidates(thread):
return CANDIDATES
# after
participant_names = [a.name for a in agents]
def candidates(thread):
wanted = ["coder", "critic"]
return [n for n in wanted if n in participant_names] or participant_names Defensive patterns
Strategy: validation
Validate before calling
def candidates(thread):
wanted = compute_wanted(thread)
valid = [n for n in wanted if n in participant_names]
return valid if valid else list(participant_names) Type guard
def all_valid_participants(names: Sequence[str], participant_names: Sequence[str]) -> bool:
return all(n in participant_names for n in names) Prevention
- Intersect any computed candidate list with the live participant set.
- Regenerate hardcoded name lists whenever participants change.
When it happens
Trigger: candidate_func returns names from a stale/hardcoded list, an agent object's repr, or names with typos/case differences relative to the actual participants.
Common situations: Hardcoding candidate names at module level then renaming agents later; building candidates from a different team's participant list; mixing display names with agent.name values.
Related errors
- Candidate function must return a non-empty list of participa
- Selector function returned an invalid speaker name: {speaker
- 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/271d85928c49c44c.
Report an issue: GitHub.