googleapis/mcp-toolbox · error
unable to get column names: %w
Error message
unable to get column names: %w
What it means
sqlite RunSQL (internal/sources/sqlite/sqlite.go:115) calls rows.Columns() to retrieve result column names after a successful query. If the rows handle has already been invalidated (connection closed, driver error) the call fails and is wrapped as "unable to get column names". This is rare because the query itself already succeeded.
Source
Thrown at internal/sources/sqlite/sqlite.go:115
}
func (s *Source) SQLiteDB() *sql.DB {
return s.Db
}
func (s *Source) RunSQL(ctx context.Context, statement string, params []any) (any, error) {
// Execute the SQL query with parameters
statement = sqlcommenter.PrependComment(ctx, statement, SourceType, s.SQLCommenter)
rows, err := s.SQLiteDB().QueryContext(ctx, statement, params...)
if err != nil {
return nil, fmt.Errorf("unable to execute query: %w", err)
}
defer rows.Close()
// Get column names
cols, err := rows.Columns()
if err != nil {
return nil, fmt.Errorf("unable to get column names: %w", err)
}
// The sqlite driver does not support ColumnTypes, so we can't get the
// underlying database type of the columns. We'll have to rely on the
// generic `any` type and then handle the JSON data separately.
rawValues := make([]any, len(cols))
values := make([]any, len(cols))
for i := range rawValues {
values[i] = &rawValues[i]
}
// Prepare the result slice
out := []any{}
for rows.Next() {
if err := rows.Scan(values...); err != nil {
return nil, fmt.Errorf("unable to scan row: %w", err)
}
View on GitHub (pinned to 8cc6e09de2)
Solutions
- Increase the context/request timeout if deadlines are tight
- Retry the query — this is usually transient
- Check for connection drops if using a non-local sqlite driver (e.g. a proxy/turso-style backend)
- If reproducible, file an issue with the sqlite driver in use
Defensive patterns
Strategy: retry
Try / catch
res, err := source.RunSQL(ctx, stmt, params)
if err != nil && strings.Contains(err.Error(), "unable to get column names") {
// transient: retry once with backoff
res, err = source.RunSQL(ctx, stmt, params)
} Prevention
- Use generous context timeouts for query calls
- Retry transient metadata failures once
- Keep the sqlite driver up to date
When it happens
Trigger: RunSQL where rows.Columns() fails after QueryContext succeeded — typically a driver-level connection failure occurring between query execution and metadata retrieval, or context cancellation in between.
Common situations: Context deadline hit right after query start; underlying connection dropped (unusual for in-process SQLite, more plausible with a networked driver); driver bug.
Understand the failure class
Background: Database query failed: Internal Server Error 500s wrapping SQL, Prisma, and connection failures — what to check first — this error's family across 16 libraries.
Related errors
- unable to create db connection: %w
- unable to connect successfully: %w
- unable to execute query: %w
- unable to scan row: %w
- error iterating rows: %w
AI-assisted analysis of googleapis/mcp-toolbox@8cc6e09de2 (2026-09-05).
Data as JSON: /api/errors/c858a6ae95fbbcd5.
Report an issue: GitHub.