HKUDS/DeepTutor · error · GraphRagStructuredOutputError

graphrag_model_incompatible

graphrag_model_incompatible

Error message

The model did not accept or return the structured output required by GraphRAG.

What it means

GraphRagStructuredOutputError (code graphrag_model_incompatible): the model's response to a GraphRAG structured-output request could not be parsed/validated (json.JSONDecodeError, TypeError, pydantic ValidationError, ValueError) and truncation was not the cause. The model either ignored the schema or returned malformed JSON.

Source

Thrown at deeptutor/services/rag/pipelines/graphrag/completion_adapter.py:128

    fallback["messages"] = _messages_with_schema(fallback["messages"], response_format)
    fallback.pop("response_format", None)
    return fallback


def _format_response(response: Any, response_format: type[BaseModel]) -> Any:
    from graphrag_llm.utils import structure_completion_response

    try:
        response.formatted_response = structure_completion_response(
            response.content,
            response_format,
        )
    except (json.JSONDecodeError, TypeError, ValidationError, ValueError) as error:
        choices = getattr(response, "choices", None)
        finish_reason = getattr(choices[0], "finish_reason", None) if choices else None
        if finish_reason in {"length", "max_tokens"}:
            raise GraphRagStructuredOutputTruncatedError(MODEL_OUTPUT_TRUNCATED_MESSAGE) from error
        raise GraphRagStructuredOutputError(MODEL_INCOMPATIBLE_MESSAGE) from error
    return response


def _native_validation_error(error: BaseException) -> bool:
    return isinstance(error, (json.JSONDecodeError, ValidationError))


def _fallback_sync(instance: Any, kwargs: dict[str, Any], response_format: type[BaseModel]) -> Any:
    fallback = _format_fallback_kwargs(kwargs, response_format)
    if fallback.get("stream"):
        raise ValueError("response_format is not supported for streaming completions.")
    messages = fallback.pop("messages")
    if isinstance(messages, str):
        messages = [{"role": "user", "content": messages}]
    request_metrics = fallback.pop("metrics", None) or {}
    if not instance._track_metrics:
        request_metrics = None
    try:

View on GitHub (pinned to 3e82f13042)

Solutions

  1. Switch the active chat model to one with verified structured-output support (recent OpenAI/Anthropic/DeepSeek models).
  2. Enable/force JSON mode on the provider endpoint.
  3. Update the model or serving stack so response_format is honored.
  4. If using a proxy, verify it forwards the response_format field.

Example fix

# before: model ignores response_format
model = "local-mistral-7b"
# after
model = "gpt-4o"  # or another model with native structured output
Defensive patterns

Strategy: fallback

Try / catch

try:
    await build(root)
except GraphRagStructuredOutputError as e:
    if e.code == "graphrag_model_incompatible":
        switch_to_structured_output_model()
    raise

Prevention

When it happens

Trigger: A chat model that doesn't support response_format / structured outputs returns prose or schema-violating JSON during GraphRAG indexing or the probe (_probe_completion_model_impl / _fallback_sync / _fallback_async).

Common situations: Using an OpenAI-compatible proxy or local model (llama.cpp, vLLM, older TGI) that ignores json_schema response_format; models that wrap JSON in markdown fences; mismatched pydantic schema expectations across GraphRAG versions.

Related errors


AI-assisted analysis of HKUDS/DeepTutor@3e82f13042 (2026-08-27). Data as JSON: /api/errors/d4dcb90c09ffcb4b. Report an issue: GitHub.