{"record":{"id":"aa0d8e1234846f2e","repo":"zylon-ai/private-gpt","slug":"tool-context-is-provided-but-no-tools-are-specifi","errorCode":null,"errorMessage":"Tool context is provided, but no tools are specified. Please provide tools to use with the tool context.","messagePattern":"Tool context is provided, but no tools are specified\\. Please provide tools to use with the tool context\\.","errorType":"validation","errorClass":"ValueError","httpStatus":422,"severity":"error","filePath":"private_gpt/server/chat/chat_models.py","lineNumber":338,"sourceCode":"                    if block is None:\n                        raise ValueError(f\"Block cannot be None: {message}\")\n\n        if self.messages[-1].role not in self._valid_last_message_roles:\n            raise ValueError(\n                f\"Last message role must be one of {self._valid_last_message_roles}, but got {self.messages[-1].role}\"\n            )\n\n        # Check tools and tool choice\n        if self.tools and self.tool_choice and self.tool_choice.type == \"tool\":\n            if not self.tools:\n                raise ValueError(\"Tool choice is set, but no tools are provided.\")\n            if self.tool_choice.name not in [tool.name for tool in self.tools]:\n                raise ValueError(\n                    f\"Tool choice '{self.tool_choice}' is not in the provided tools.\"\n                )\n\n        if not self.tools and self.tool_context:\n            raise ValueError(\n                \"Tool context is provided, but no tools are specified. \"\n                \"Please provide tools to use with the tool context.\"\n            )\n\n        # Apply global tool context to tools without specific context\n        if self.tools is not None:\n            global_tool_context = self.tool_context or []\n            if global_tool_context:\n                for tool in self.tools:\n                    if tool.context is None:\n                        tool.context = global_tool_context\n\n        has_structured_output = bool(self.output_config and self.output_config.format)\n        if self.response_format.type == ResponseFormatType.json_schema:\n            has_structured_output = True\n\n        # Check that we don't have tools when structured output is enabled\n        if has_structured_output:","sourceCodeStart":320,"sourceCodeEnd":356,"githubUrl":"https://github.com/zylon-ai/private-gpt/blob/4a030776a31a901ad80b1bf4d7faa2c1a367efbb/private_gpt/server/chat/chat_models.py#L320-L356","documentation":"ChatBody rejects requests that supply tool_context (metadata for tool execution, e.g. SQL connection details) without any tools. Tool context only has meaning attached to tools, so the validator fails fast rather than silently discarding the configuration.","triggerScenarios":"Sending tool_context=[...] with tools omitted or empty; a client config where tools are conditionally added and the condition evaluated false while tool_context is unconditional; enabling a 'database access' setting that only sets tool_context.","commonSituations":"Config-driven request builders where tools and tool_context come from different settings files; disabling tools via env flag but leaving tool_context in the payload; copy-pasting tool payloads and deleting the tools field.","solutions":["Send tool_context only when tools is non-empty; make the two fields conditional on the same flag.","If you intended no tools, remove tool_context from the request body.","Validate the pairing client-side before the request."],"exampleFix":"# before\nbody = {\"messages\": m, \"tool_context\": ctx}  # tools omitted\n\n# after\nbody = {\"messages\": m, \"tools\": tools, \"tool_context\": ctx} if tools else {\"messages\": m}","handlingStrategy":"validation","validationCode":"if not tools:\n    body.pop('tool_context', None)\nassert not (tool_context and not tools), 'tool_context requires tools'","typeGuard":"def tool_fields_consistent(tools: list | None, ctx: list | None) -> bool:\n    return not (not tools and ctx)","tryCatchPattern":"except ValidationError as e:\n    if 'tool context is provided' in str(e).lower():\n        del body['tool_context']; retry()\n    else:\n        raise","preventionTips":["Bind tool_context and tools to the same feature flag","Build the request body per mode (tools vs no-tools)","Lint request templates for orphan tool_context"],"tags":["validation","tools","configuration","chat-api"],"backgroundTag":null,"analyzedSha":"4a030776a31a901ad80b1bf4d7faa2c1a367efbb","analyzedAt":"2026-08-15T03:51:26.951Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}