Skip to content

Query Errors

deep_db_agents.query_errors

Turns query execution exceptions into feedback for the agent.

When the LLM generates an invalid query (syntax error, non-existent table/column/field, incompatible operator or type, ...), the database driver raises an exception. Instead of propagating it opaquely — interrupting the agent's turn — the tools convert it into a structured message the agent can read to fix the query on the next attempt: error handling becomes part of the feedback loop, not a terminal failure.

Whitelist/scope violations (QueryNotAllowedError: out-of-scope index/collection, disallowed stage or write clauses, malformed query) also flow through here and become feedback: the forbidden operation is still not executed — it is blocked before reaching the driver — but the rejection is communicated to the agent as a corrective message rather than interrupting the turn. Budget and threshold guardrails (GuardrailError), on the other hand, remain hard exceptions signaling a session limit that must not be bypassed.

format_query_error

format_query_error(exc: Exception, *, query: str | None = None, what: str = 'query') -> str

Format a driver exception as corrective feedback for the agent.

Parameters:

Name Type Description Default
exc Exception

The exception raised during execution (database driver error).

required
query str | None

The text of the submitted query/pipeline; included in the feedback if present, so the agent sees exactly what it got wrong.

None
what str

Label for the executed construct ("query", "pipeline", "Cypher query"), used in the message.

'query'

Returns:

Name Type Description
str str

A multi-line message describing the failure, suitable for returning to

str

the agent as tool output.

Source code in src/deep_db_agents/query_errors.py
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
def format_query_error(exc: Exception, *, query: str | None = None, what: str = "query") -> str:
    """Format a driver exception as corrective feedback for the agent.

    Args:
        exc: The exception raised during execution (database driver error).
        query: The text of the submitted query/pipeline; included in the feedback if
            present, so the agent sees exactly what it got wrong.
        what: Label for the executed construct (``"query"``, ``"pipeline"``,
            ``"Cypher query"``), used in the message.

    Returns:
        str: A multi-line message describing the failure, suitable for returning to
        the agent as tool output.
    """
    detail = _redact_secrets(str(exc).strip()) or "(no detail provided by the driver)"
    # The error becomes feedback for the agent, but it is also an observable event on
    # the operator side (failed or blocked query): logged with credentials already
    # redacted from the detail.
    _logger.warning("%s not executed: %s: %s", what, type(exc).__name__, detail)
    lines = [
        f"Error: the {what} was NOT executed by the database.",
        f"Error type: {type(exc).__name__}",
        f"Detail: {detail}",
    ]
    if query:
        text = query.strip()
        if len(text) > _MAX_QUERY_CHARS:
            text = text[:_MAX_QUERY_CHARS] + " …[truncated]"
        lines.append(f"{what.capitalize()} submitted:\n{text}")
    lines.append(
        f"The database rejected the request. Fix the {what} based on the error "
        "detail (syntax, table/column/field names, types or operators) and retry; "
        "if needed, inspect the schema first with the exploration tools."
    )
    return "\n".join(lines)