I have made another post because I believe my exploration and solution are different enough from the original to justify it, but I can merge if anyone disagrees. So, I believe I have figured out what is the cause of the issue with stat_summary and your current solution.
I believe that stat_summary calculates its summary statistic for each unique value of x, when the x variable takes on integer values.
library(tidyverse)
sapply(mpg, class)
#> manufacturer model displ year cyl trans
#> "character" "character" "numeric" "integer" "integer" "character"
#> drv cty hwy fl class
#> "character" "integer" "integer" "character" "character"
See below the same before when using hwy and cty, even when both explicitly converted to numeric rather than integer vectors.
mpg2 <- mpg %>%
mutate(hwy = as.numeric(hwy),
cty = as.numeric(cty))
sapply(mpg2, class)
#> manufacturer model displ year cyl trans
#> "character" "character" "numeric" "integer" "integer" "character"
#> drv cty hwy fl class
#> "character" "numeric" "numeric" "character" "character"
mpg2 %>%
ggplot(aes(x=hwy, group=cyl))+
geom_histogram()+
facet_grid(~cyl)+
stat_summary(aes(xintercept=stat(x), y=0), fun = median, geom = 'vline')

And example with cty:
mpg2 %>%
ggplot(aes(x=cty, group=cyl))+
geom_histogram()+
facet_grid(~cyl)+
stat_summary(aes(xintercept=stat(x), y=0), fun = median, geom = 'vline')

However, if we make a slight adjustment to cty prior to plotting, adding a minute decimal point, we get the desired behavior.
mpg %>%
mutate(cty = cty + .000001) %>%
ggplot(aes(x=cty, group=cyl))+
geom_histogram()+
facet_grid(~cyl)+
stat_summary(aes(xintercept=stat(x), y=0), fun = median, geom = 'vline')

And we see the same behavior with hwy.
mpg %>%
mutate(hwy = hwy + .000001) %>%
ggplot(aes(x=hwy, group=cyl))+
geom_histogram()+
facet_grid(~cyl)+
stat_summary(aes(xintercept=stat(x), y=0), fun = median, geom = 'vline')
Of course, this isn't necessarily a desirable solution. Since we are mapping vertical lines, we can instead create a new aes where we instead plot our xintercept as a function of y, and provide a single dummy variable to x within our data range. This then tricks the system into plotting only one median from our single x value, and gives us the desired graph.
mpg %>%
ggplot(aes(x=cty, group = cyl))+
geom_histogram()+
facet_grid(~cyl)+
stat_summary(aes(x = 3, y = cty, xintercept = stat(y)), fun = median, geom = 'vline')

And there we go! Quite convoluted, and don't really like it as a solution, but I believe this is the way you have to go if using stat_summary.