{"record":{"id":"7771f8c45f3cb9f5","repo":"oraios/serena","slug":"cannot-use-both-fixed-tools-and-excluded-tools-inc","errorCode":null,"errorMessage":"Cannot use both fixed_tools and excluded_tools/included_optional_tools at the same time.","messagePattern":"Cannot use both fixed_tools and excluded_tools/included_optional_tools at the same time\\.","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"src/serena/config/serena_config.py","lineNumber":168,"sourceCode":"\n    excluded_tools: Sequence[str] = ()\n    \"\"\"\n    the names of tools to exclude from use [incremental mode]\n    \"\"\"\n    included_optional_tools: Sequence[str] = ()\n    \"\"\"\n    the names of optional tools to include [incremental mode]\n    \"\"\"\n    fixed_tools: Sequence[str] = ()\n    \"\"\"\n    the names of tools to use as a fixed set of tools [fixed mode]\n    \"\"\"\n\n    def is_fixed_tool_set(self) -> bool:\n        num_fixed = len(self.fixed_tools)\n        num_incremental = len(self.excluded_tools) + len(self.included_optional_tools)\n        if num_fixed > 0 and num_incremental > 0:\n            raise ValueError(\"Cannot use both fixed_tools and excluded_tools/included_optional_tools at the same time.\")\n        return num_fixed > 0\n\n\n@dataclass\nclass NamedToolInclusionDefinition(ToolInclusionDefinition):\n    name: str | None = None\n\n    def __str__(self) -> str:\n        return f\"ToolInclusionDefinition[{self.name}]\"\n\n\n@dataclass\nclass ModeSelectionDefinition:\n    default_modes: Sequence[str] | None = None\n\n\n@dataclass\nclass ModeSelectionDefinitionWithBaseModes(ModeSelectionDefinition):","sourceCodeStart":150,"sourceCodeEnd":186,"githubUrl":"https://github.com/oraios/serena/blob/7fcbca7e62555ec2287ddb2f083caee805848ea6/src/serena/config/serena_config.py#L150-L186","documentation":"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.","triggerScenarios":"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().","commonSituations":"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.","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."],"exampleFix":"# before\ntools:\n  fixed_tools: [read_file, execute_shell_command]\n  excluded_tools: [write_memory]\n# after\ntools:\n  excluded_tools: [write_memory]\n# or, for an explicit allowlist:\n# tools:\n#   fixed_tools: [read_file, execute_shell_command]","handlingStrategy":"validation","validationCode":"def validate_tool_definition(tools: dict) -> None:\n    fixed = len(tools.get(\"fixed_tools\", []))\n    incremental = len(tools.get(\"excluded_tools\", [])) + len(tools.get(\"included_optional_tools\", []))\n    if fixed > 0 and incremental > 0:\n        raise ValueError(\"Use either fixed_tools OR excluded_tools/included_optional_tools, not both.\")","typeGuard":"def is_fixed_tool_set_cfg(tools: dict) -> bool:\n    return len(tools.get(\"fixed_tools\", [])) > 0 and not (tools.get(\"excluded_tools\") or tools.get(\"included_optional_tools\"))","tryCatchPattern":"try:\n    tool_def.apply(backend)\nexcept ValueError as e:\n    if \"fixed_tools\" in str(e):\n        tool_def.fixed_tools = []\n        tool_def.apply(backend)\n    else:\n        raise","preventionTips":["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."],"tags":["python","configuration","validation"],"backgroundTag":"conflicting-config-options","analyzedSha":"7fcbca7e62555ec2287ddb2f083caee805848ea6","analyzedAt":"2026-08-29T00:04:09.619Z","schemaVersion":2},"datasetVersion":"2026-08-29T02:17:18.158Z"}