There's no compile-time error checking and words can push/pop arbitrary amounts of data to/from the stack. This means that if a program grows beyond the point where you can keep the whole thing in your head, it's a nightmare to maintain since bugs like giving a word the wrong number of parameters can cause a cascading series of errors that's challenging to unravel. I don't think it's a coincidence that Forth advocates have a philosophy of "if a problem's too complex, redefine the requirements so you can fit it all in your head". Personally, while I find Forth fun to write trivial programs in, I would rather write nontrivial programs even in assembly than in Forth.