zylon-ai/private-gpt · error · ValueError

Tool context is provided, but no tools are specified. Please

Error message

Tool context is provided, but no tools are specified. Please provide tools to use with the tool context.

What it means

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.

Source

Thrown at private_gpt/server/chat/chat_models.py:338

                    if block is None:
                        raise ValueError(f"Block cannot be None: {message}")

        if self.messages[-1].role not in self._valid_last_message_roles:
            raise ValueError(
                f"Last message role must be one of {self._valid_last_message_roles}, but got {self.messages[-1].role}"
            )

        # Check tools and tool choice
        if self.tools and self.tool_choice and self.tool_choice.type == "tool":
            if not self.tools:
                raise ValueError("Tool choice is set, but no tools are provided.")
            if self.tool_choice.name not in [tool.name for tool in self.tools]:
                raise ValueError(
                    f"Tool choice '{self.tool_choice}' is not in the provided tools."
                )

        if not self.tools and self.tool_context:
            raise ValueError(
                "Tool context is provided, but no tools are specified. "
                "Please provide tools to use with the tool context."
            )

        # Apply global tool context to tools without specific context
        if self.tools is not None:
            global_tool_context = self.tool_context or []
            if global_tool_context:
                for tool in self.tools:
                    if tool.context is None:
                        tool.context = global_tool_context

        has_structured_output = bool(self.output_config and self.output_config.format)
        if self.response_format.type == ResponseFormatType.json_schema:
            has_structured_output = True

        # Check that we don't have tools when structured output is enabled
        if has_structured_output:

View on GitHub (pinned to 4a030776a3)

Solutions

  1. Send tool_context only when tools is non-empty; make the two fields conditional on the same flag.
  2. If you intended no tools, remove tool_context from the request body.
  3. Validate the pairing client-side before the request.

Example fix

# before
body = {"messages": m, "tool_context": ctx}  # tools omitted

# after
body = {"messages": m, "tools": tools, "tool_context": ctx} if tools else {"messages": m}
Defensive patterns

Strategy: validation

Validate before calling

if not tools:
    body.pop('tool_context', None)
assert not (tool_context and not tools), 'tool_context requires tools'

Type guard

def tool_fields_consistent(tools: list | None, ctx: list | None) -> bool:
    return not (not tools and ctx)

Try / catch

except ValidationError as e:
    if 'tool context is provided' in str(e).lower():
        del body['tool_context']; retry()
    else:
        raise

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Related errors


AI-assisted analysis of zylon-ai/private-gpt@4a030776a3 (2026-08-15). Data as JSON: /api/errors/aa0d8e1234846f2e. Report an issue: GitHub.