zylon-ai/private-gpt · error · ValueError

Tools are not supported when structured output is enabled.

Error message

Tools are not supported when structured output is enabled.

What it means

The generic branch of the same structured-output guard: structured output is considered enabled (output_config.format set, or json_schema response_format) and tools are present, so ChatBody raises. It exists because this backend cannot run tool-calling loops while simultaneously constraining the final message to a structured schema.

Source

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

        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:
            if self.tools:
                if self.response_format.type == ResponseFormatType.json_schema:
                    raise ValueError(
                        "Tools are not supported when response_format is set to json_schema"
                    )
                raise ValueError(
                    "Tools are not supported when structured output is enabled."
                )
            if self.mcp_servers:
                raise ValueError(
                    "MCP servers are not supported when structured output is enabled."
                )
            if system.citations.enabled:
                raise ValueError(
                    "Citations are not supported when structured output is enabled."
                )

        # Check unique tools
        if self.tools:
            tool_names = [tool.name for tool in self.tools]
            if len(tool_names) != len(set(tool_names)):
                raise ValueError(
                    "Duplicate tool names found in the tools list."
                    f" Provided tools: {self.tools}"

View on GitHub (pinned to 4a030776a3)

Solutions

  1. Pick one mode per request: structured output OR tools.
  2. Make the request builder assert not (output_config and tools) before sending.
  3. If tool-driven structured data is needed, model the schema as a tool and use tool_choice instead of output_config.

Example fix

# before
body = {"messages": m, "tools": tools, "output_config": {"format": fmt}}

# after
body = {"messages": m, "output_config": {"format": fmt}} if fmt else {"messages": m, "tools": tools}
Defensive patterns

Strategy: validation

Validate before calling

structured = bool((body.get('output_config') or {}).get('format'))
assert not (structured and body.get('tools')), 'structured output excludes tools'

Type guard

def no_structured_tool_clash(body: dict) -> bool:
    structured = bool((body.get('output_config') or {}).get('format')) or \
        body.get('response_format', {}).get('type') == 'json_schema'
    return not (structured and body.get('tools'))

Try / catch

except ValidationError as e:
    if 'structured output' in str(e):
        body.pop('tools', None); retry()
    else:
        raise

Prevention

When it happens

Trigger: Setting output_config (e.g. {'format': ...}) alongside a non-empty tools list; enabling citation-free structured mode while tools remain registered from a previous request template.

Common situations: Feature flags for 'structured answers' and 'tools' both enabled; merging request payloads from different code paths; configuration presets that include tools by default.

Related errors


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