This difference may be relevant:
R.<x,y> = ZZ[]
I = R.ideal(4*x^2,9*y^2)
I.reduce(x^2*y^2) #correctly returns 0
(x^2*y^2).reduce(I) #does not return 0
(x^2*y^2).reduce(I.groebner_basis()) #does return 0
The documentation of x.reduce suggests that if the argument is an ideal for which sage can compute a strong groebner basis, then the reduction should take place with respect to a strong groebner basis. It looks like it's not doing that.