googleapis/mcp-toolbox · error
unable to execute query: %w
Error message
unable to execute query: %w
What it means
Returned by the cloud-sql-mssql source's RunSQL when s.MSSQLDB().QueryContext fails to execute the supplied statement. This wraps any driver-level execution error: SQL syntax errors, missing objects, permission denials, timeouts, or dropped connections. The error occurs before any rows are read, so results.Close() is never deferred in this path.
Source
Thrown at internal/sources/cloudsqlmssql/cloud_sql_mssql.go:118
func (s *Source) SourceType() string {
// Returns Cloud SQL MSSQL source type
return SourceType
}
func (s *Source) ToConfig() sources.SourceConfig {
return s.Config
}
func (s *Source) MSSQLDB() *sql.DB {
// Returns a Cloud SQL MSSQL database connection pool
return s.Db
}
func (s *Source) RunSQL(ctx context.Context, statement string, params []any) (any, error) {
results, err := s.MSSQLDB().QueryContext(ctx, statement, params...)
if err != nil {
return nil, fmt.Errorf("unable to execute query: %w", err)
}
defer results.Close()
cols, err := results.Columns()
// If Columns() errors, it might be a DDL/DML without an OUTPUT clause.
// We proceed, and results.Err() will catch actual query execution errors.
// 'out' will remain an empty slice if cols is empty or err is not nil here.
out := []any{}
if err == nil && len(cols) > 0 {
// create an array of values for each column, which can be re-used to scan each row
rawValues := make([]any, len(cols))
values := make([]any, len(cols))
for i := range rawValues {
values[i] = &rawValues[i]
}
for results.Next() {
scanErr := results.Scan(values...)View on GitHub (pinned to 8cc6e09de2)
Solutions
- Read the wrapped driver error for the exact SQL Server message (line number, error code)
- Run the statement manually in SSMS/sqlcmd with the same user to reproduce
- Fix SQL syntax or object names in the tool's statement/parameters
- Grant the configured user the needed SELECT/EXEC permissions
- Increase the request context timeout if the query is long-running
Example fix
// before SELECT * FORM users WHERE id = @p1; // after SELECT * FROM users WHERE id = @p1;
Defensive patterns
Strategy: validation
Validate before calling
// Validate statement non-empty and table names quoted before invoking RunSQL
if strings.TrimSpace(statement) == "" {
return errors.New("statement must not be empty")
} Try / catch
results, err := src.RunSQL(ctx, statement, params)
if err != nil {
if strings.Contains(err.Error(), "unable to execute query") {
// surface wrapped driver error to the user and let the LLM retry with corrected SQL
return fmt.Errorf("SQL rejected by SQL Server: %w", err)
}
return err
} Prevention
- Test all configured tool statements manually in SSMS/sqlcmd before deployment
- Grant the configured SQL Server user only the specific permissions the tools need
- Use parameterized statements rather than string interpolation
- Set sensible context timeouts matching expected query durations
When it happens
Trigger: Any tool invocation that reaches Source.RunSQL (e.g. execute-sql tool) with a statement the SQL Server rejects or cannot run: invalid T-SQL syntax, referencing a non-existent table/column, insufficient permissions, parameter count/type mismatch, context deadline exceeded, or connection already closed.
Common situations: LLM-generated SQL with syntax errors, querying tables the configured user lacks SELECT rights on, very long queries hitting a context timeout, stale connections after an instance restart, placeholders (!) param style mismatches with sqlserver driver.
Related errors
- unable to parse row: %w
- errors encountered during query execution or row processing:
- unable to execute query: %w
- unable to execute query: %w
- unable to execute query: %w
AI-assisted analysis of googleapis/mcp-toolbox@8cc6e09de2 (2026-09-05).
Data as JSON: /api/errors/474b068d3240b3b7.
Report an issue: GitHub.