Skip to content

fix(bigquery-execute-sql): invalid BigQuery query errors are surfaced as MCP 500s #3055

@jack-larch

Description

@jack-larch

Description

When the bigquery-execute-sql tool receives a user/query validation error from BigQuery during the dry-run phase, it currently wraps that error as a ClientServerError with http.StatusInternalServerError.

That classification causes the MCP layer to return a JSON-RPC internal error and an HTTP 500 instead of a normal tool error result. In practice, this makes LLM clients treat normal BigQuery SQL mistakes as transport failures.

Repro

In our sandbox, this showed up when an MCP client called execute_sql with invalid-but-common BigQuery SQL such as:

SELECT *
FROM `project.dataset.table`
WHERE created_at >= DATE_SUB(CURRENT_DATE(), INTERVAL 6 MONTH)

against a TIMESTAMP column, or with DATE_TRUNC(timestamp_col, WEEK) instead of TIMESTAMP_TRUNC(...).

BigQuery correctly returns a 400-series query validation error like invalidQuery / No matching signature ..., but the toolbox currently turns that into an MCP HTTP 500.

Root cause

internal/tools/bigquery/bigqueryexecutesql/bigqueryexecutesql.go currently does:

if err != nil {
    return nil, util.NewClientServerError("query validation failed", http.StatusInternalServerError, err)
}

The similar bigquery-sql tool already uses util.ProcessGcpError(err) instead, which preserves auth failures as transport errors but treats normal GCP request/query failures as agent/tool errors.

Expected behavior

For invalid BigQuery SQL submitted through MCP:

  • the toolbox should not emit HTTP 500
  • the MCP response should be a normal tool result with isError: true
  • the BigQuery error message should stay visible to the client so the model/user can correct the query

Proposed fix

Use util.ProcessGcpError(err) in bigquery-execute-sql for dry-run validation failures, matching the existing bigquery-sql path.

I have a small PR ready with that change plus a focused regression test for the GCP error classifier.

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions