{"record":{"id":"e4d2a8e341a9c8ac","repo":"googleapis/mcp-toolbox","slug":"unable-to-get-columns-w","errorCode":null,"errorMessage":"unable to get columns: %w","messagePattern":"unable to get columns: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/sources/firebird/firebird.go","lineNumber":113,"sourceCode":"\nfunc (s *Source) ToConfig() sources.SourceConfig {\n\treturn s.Config\n}\n\nfunc (s *Source) FirebirdDB() *sql.DB {\n\treturn s.Db\n}\n\nfunc (s *Source) RunSQL(ctx context.Context, statement string, params []any) (any, error) {\n\trows, err := s.FirebirdDB().QueryContext(ctx, statement, params...)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"unable to execute query: %w\", err)\n\t}\n\tdefer rows.Close()\n\n\tcols, err := rows.Columns()\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"unable to get columns: %w\", err)\n\t}\n\n\tvalues := make([]any, len(cols))\n\tscanArgs := make([]any, len(values))\n\tfor i := range values {\n\t\tscanArgs[i] = &values[i]\n\t}\n\n\tout := []any{}\n\tfor rows.Next() {\n\n\t\terr = rows.Scan(scanArgs...)\n\t\tif err != nil {\n\t\t\treturn nil, fmt.Errorf(\"unable to parse row: %w\", err)\n\t\t}\n\n\t\tvMap := make(map[string]any)\n\t\tfor i, col := range cols {","sourceCodeStart":95,"sourceCodeEnd":131,"githubUrl":"https://github.com/googleapis/mcp-toolbox/blob/8cc6e09de2ad7b8bffc77751799585a1401a48eb/internal/sources/firebird/firebird.go#L95-L131","documentation":"Wraps the error from rows.Columns() after a successful query in RunSQL. In database/sql this rarely fails, but the Firebird driver can fail here when the statement metadata is unavailable — typically for non-SELECT statements (DML without RETURNING) or a connection drop between query and metadata fetch.","triggerScenarios":"RunSQL called with an INSERT/UPDATE/DELETE without RETURNING clause (no result-set metadata), or the underlying connection died after rows were obtained.","commonSituations":"Using RunSQL for DDL/DML statements that return no result set; driver quirks with EXECUTE BLOCK statements; network interruption mid-call.","solutions":["Use statements that return a result set, or add RETURNING clause for DML needing columns","Handle no-metadata statements separately (use ExecContext for DML/DDL)","Check connection stability (SetConnMaxLifetime, server keepalive) if intermittent"],"exampleFix":"// before\ncols, err := rows.Columns()\nif err != nil {\n    return nil, fmt.Errorf(\"unable to get columns: %w\", err)\n}\n// after\ncols, err := rows.Columns()\nif err != nil {\n    if errors.Is(err, sql.ErrNoRows) || errors.Is(err, driver.ErrSkip) {\n        return map[string]any{\"status\": \"statement executed, no result set\"}, nil\n    }\n    return nil, fmt.Errorf(\"unable to get columns: %w\", err)\n}","handlingStrategy":"fallback","validationCode":"// Prefer statements with result metadata; detect bare DML first\nupper := strings.ToUpper(strings.TrimSpace(statement))\nif strings.HasPrefix(upper, \"INSERT\") || strings.HasPrefix(upper, \"UPDATE\") ||\n   strings.HasPrefix(upper, \"DELETE\") || strings.HasPrefix(upper, \"CREATE\") {\n    // expect no result set; consider ExecContext path instead\n}","typeGuard":"func hasNoMetadata(err error) bool {\n    return err != nil && (errors.Is(err, sql.ErrNoRows) || strings.Contains(err.Error(), \"no result set\"))\n}","tryCatchPattern":"cols, err := rows.Columns()\nif err != nil {\n    if hasNoMetadata(err) {\n        return map[string]any{\"status\": \"executed\", \"rows\": 0}, nil\n    }\n    return nil, fmt.Errorf(\"unable to get columns: %w\", err)\n}","preventionTips":["Route non-SELECT statements to an execute path, not the row-reading path","Add RETURNING clauses when DML results are needed","Keep the firebirdsql driver updated for metadata-handling fixes","Avoid EXECUTE BLOCK shapes known to omit metadata in this driver"],"tags":["firebird","resultset","metadata"],"backgroundTag":"resultset-metadata-failed","analyzedSha":"8cc6e09de2ad7b8bffc77751799585a1401a48eb","analyzedAt":"2026-09-05T01:10:36.887Z","contentChangedAt":"2026-09-05T01:10:36.887Z","schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}