zylon-ai/private-gpt · error · ValueError

Failed to generate SQL query

Error message

Failed to generate SQL query

What it means

Raised after a successful LLM chat call when none of the response content blocks is a TextBlock — i.e. the model returned only non-text content (empty response, tool calls, or an unexpected block type). The SQL extraction path never gets text to parse, so the generator gives up with this generic error instead of returning empty SQL.

Source

Thrown at private_gpt/components/tabular/database_query_generator.py:909

                system=ResolvedSystemConfig(
                    prompt=system_prompt, use_default_prompt=False
                ),
                condensation=CondensationConfig(enabled=False),
                sampling_params=sampling_params,
            )
        )

        # find the first text block in the response
        for block in response.content:
            if isinstance(block, TextBlock):
                raw_text = block.text
                # despite the instructions, the LLM might
                # generate markdown like ```sql ... ```
                # so we try to extract the SQL code from it
                # remove the prefix and suffix if present
                return self._extract_sql_code(raw_text, transpile_sql=False)

        raise ValueError("Failed to generate SQL query")

    def _transpile_sql(self, sql: str) -> str:
        if not self._dialect:
            return sql

        for read_dialect in Dialects:
            if read_dialect.value == self._dialect:
                continue

            with contextlib.suppress(ParseError):
                result = "\n".join(
                    sqlglot.transpile(sql, read=read_dialect, write=self._dialect)
                )

                if result:
                    return result

        try:

View on GitHub (pinned to 4a030776a3)

Solutions

  1. Retry the generation request — transient empty completions often succeed on a second attempt
  2. Free up output tokens: reduce schema size / history so available_tokens for generation is comfortably large
  3. Inspect response.content types in a debug hook to confirm which block type the model actually returned and adjust prompt/model accordingly

Example fix

# before
result = await generator.generate(...)  # raises ValueError
# after
for attempt in range(2):
    try:
        result = await generator.generate(...)
        break
    except ValueError as e:
        if "Failed to generate SQL" not in str(e) or attempt == 1:
            raise
Defensive patterns

Strategy: retry

Validate before calling

if not response.content or not any(
    hasattr(b, "text") for b in response.content
):
    raise ValueError("model returned no text block; retrying")

Try / catch

for attempt in range(3):
    try:
        return await generator.generate(question)
    except ValueError as e:
        if "Failed to generate SQL" not in str(e) or attempt == 2:
            raise
        await asyncio.sleep(2**attempt)

Prevention

When it happens

Trigger: The chat service response contains zero TextBlock entries: model emitted an empty completion, only tool-use blocks, or the response was truncated to nothing by sampling limits (e.g. max_tokens consumed by reasoning).

Common situations: max_tokens budget from schema packing (see the 20% buffer logic) leaving almost nothing for output; a misrouted model that answers with tool calls; provider returning an empty delta list.

Related errors


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