googleapis/mcp-toolbox · error

unable to execute query: %w

Error message

unable to execute query: %w

What it means

sqlite RunSQL (internal/sources/sqlite/sqlite.go:108) executes the caller's statement via QueryContext after prepending an sqlcommenter comment. Any driver-level failure during query execution is wrapped as "unable to execute query". This covers SQL syntax errors, missing tables/columns, and lock contention.

Source

Thrown at internal/sources/sqlite/sqlite.go:108

func (s *Source) SourceType() string {
	return SourceType
}

func (s *Source) ToConfig() sources.SourceConfig {
	return s.Config
}

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]
	}

View on GitHub (pinned to 8cc6e09de2)

Solutions

  1. Read the wrapped driver error for the specific SQLite result code (e.g. SQLITE_LOCKED, SQLITE_ERROR)
  2. Test the exact statement with the sqlite3 CLI to reproduce and fix syntax/schema issues
  3. If 'database is locked', reduce concurrent writers or enable WAL mode: PRAGMA journal_mode=WAL;
  4. Verify the parameterized query's placeholder count matches the params slice length

Example fix

// before
PRAGMA journal_mode=DELETE;
// after
PRAGMA journal_mode=WAL; -- reduces writer lock contention
Defensive patterns

Strategy: try-catch

Try / catch

res, err := source.RunSQL(ctx, stmt, params)
if err != nil {
	var se *sqlite.Error
	if errors.As(err, &se) && strings.Contains(err.Error(), "locked") {
		// back off and retry, or switch to WAL mode
	}
	return fmt.Errorf("sqlite query failed: %w", err)
}

Prevention

When it happens

Trigger: RunSQL called with a statement the SQLite driver fails to run: syntax error, referencing a nonexistent table/column, database locked, datatype mismatch, or a bound parameter count mismatch.

Common situations: Tool config SQL with a typo or referencing a table that doesn't exist; concurrent writers causing 'database is locked'; passing the wrong number of parameters; sqlite database replaced/migrated without the expected schema.

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


AI-assisted analysis of googleapis/mcp-toolbox@8cc6e09de2 (2026-09-05). Data as JSON: /api/errors/cf75009373445bd2. Report an issue: GitHub.