oraios/serena · error · ValueError
Cannot use both fixed_tools and excluded_tools/included_opti
Error message
Cannot use both fixed_tools and excluded_tools/included_optional_tools at the same time.
What it means
Serena tool configuration supports two mutually exclusive modes: a fixed explicit list of tools (fixed_tools) or an incremental delta on the default set (excluded_tools plus included_optional_tools). This ValueError is raised when both modes are configured simultaneously, since the combination is ambiguous.
Source
Thrown at src/serena/config/serena_config.py:168
excluded_tools: Sequence[str] = ()
"""
the names of tools to exclude from use [incremental mode]
"""
included_optional_tools: Sequence[str] = ()
"""
the names of optional tools to include [incremental mode]
"""
fixed_tools: Sequence[str] = ()
"""
the names of tools to use as a fixed set of tools [fixed mode]
"""
def is_fixed_tool_set(self) -> bool:
num_fixed = len(self.fixed_tools)
num_incremental = len(self.excluded_tools) + len(self.included_optional_tools)
if num_fixed > 0 and num_incremental > 0:
raise ValueError("Cannot use both fixed_tools and excluded_tools/included_optional_tools at the same time.")
return num_fixed > 0
@dataclass
class NamedToolInclusionDefinition(ToolInclusionDefinition):
name: str | None = None
def __str__(self) -> str:
return f"ToolInclusionDefinition[{self.name}]"
@dataclass
class ModeSelectionDefinition:
default_modes: Sequence[str] | None = None
@dataclass
class ModeSelectionDefinitionWithBaseModes(ModeSelectionDefinition):View on GitHub (pinned to 7fcbca7e62)
Solutions
- Pick one style: remove fixed_tools and keep excluded_tools/included_optional_tools, or remove those and specify only fixed_tools.
- If you intended an incremental change to the default toolset, list the desired tools in included_optional_tools/excluded_tools and empty fixed_tools.
- If you intended an explicit allowlist, move all tool names into fixed_tools and clear the other two lists.
- Check every active layer (context, mode, project config) since layers are combined and one layer may introduce the conflict.
Example fix
# before tools: fixed_tools: [read_file, execute_shell_command] excluded_tools: [write_memory] # after tools: excluded_tools: [write_memory] # or, for an explicit allowlist: # tools: # fixed_tools: [read_file, execute_shell_command]
Defensive patterns
Strategy: validation
Validate before calling
def validate_tool_definition(tools: dict) -> None:
fixed = len(tools.get("fixed_tools", []))
incremental = len(tools.get("excluded_tools", [])) + len(tools.get("included_optional_tools", []))
if fixed > 0 and incremental > 0:
raise ValueError("Use either fixed_tools OR excluded_tools/included_optional_tools, not both.") Type guard
def is_fixed_tool_set_cfg(tools: dict) -> bool:
return len(tools.get("fixed_tools", [])) > 0 and not (tools.get("excluded_tools") or tools.get("included_optional_tools")) Try / catch
try:
tool_def.apply(backend)
except ValueError as e:
if "fixed_tools" in str(e):
tool_def.fixed_tools = []
tool_def.apply(backend)
else:
raise Prevention
- Decide on one tool-configuration style per project and document it.
- When merging contexts/modes, check that combined tool lists don't mix styles.
- Keep fixed_tools empty unless you truly want an explicit allowlist.
- Validate YAML config files in CI before deployment.
When it happens
Trigger: Defining a tool definition (in serena_config.yml, a mode, or a context) where fixed_tools is non-empty AND excluded_tools or included_optional_tools is also non-empty; detected by is_fixed_tool_set() which is called during apply().
Common situations: Merging config fragments from different sources (e.g. combining a context that uses fixed_tools with a mode that excludes tools), editing YAML by hand and leaving leftover keys, or copying an example config that mixes the two styles.
Related errors
- Unknown language backend '{backend_str}': valid values are {
- Invalid line_ending: {value!r}. Valid values are: {valid}
- Invalid language server: '{orig_language_str}'.\nValid value
- activation_command_timeout must be a number, got: {activatio
- activation_command_timeout must be positive, got: {activatio
AI-assisted analysis of oraios/serena@7fcbca7e62 (2026-08-29).
Data as JSON: /api/errors/7771f8c45f3cb9f5.
Report an issue: GitHub.