There are two things that are making code give unintuitive result. If we fix the node locations and change the path a bit, it is easier to see,
\begin{tikzpicture}[startstop/.style={circle,inner sep=0mm,outer sep=18mm,draw=black,fill=blue!50}]
\node[startstop] (A) {A};
\node[startstop] (B) at (2,0) {B};
\node[startstop] (C) at (2,-2) {C};
\draw[line width=1mm,->,>=stealth] (B) -- (C);
\draw[red,opacity=0.25] (B) circle (1.8cm+1ex) (C) circle (1.8cm+1ex);
\end{tikzpicture}

you can see that the point of the border of B is now almost on C but the point it needs to draw it is almost on B. That's the effect of outer sep that adds a separation around the node shape. If you increase back to 2cm outer sep the arrow flips.
I think you have chosen to do this because you wanted to have a relative placement of the nodes. What you should have been doing is the positioning syntax.
\usetikzlibrary{positioning}% In the preamble
\begin{tikzpicture}[startstop/.style={circle,
inner sep=0mm,outer sep=0,
draw=black,fill=blue!50,
minimum width=2cm}
]
\node[startstop] (A) {A};
\node[startstop,right= 2cm of A] (B) {B};
\node[startstop,below= 2cm of B] (C) {C};
\draw [line width=1mm,->,>=stealth] (B) -- (C);
\end{tikzpicture}
Now you can see that no matter how big the nodes are they are still 2 cm apart. You can skip the 2cm declaration and just say right = of A then the distance is read from the value of the node distance. So if you set it up in the picture options it is the same for all calls to that syntax.
Also notice that to be able to change node size, you don't need to play with the text width or height. The shape size can be changed via minimum height width keys.
More info about these are always in the manual but here are a few related posts appeared previously here.