STM32F04xx UART - Implement input rejection for strings longer than 2 bytes
How often does the main loop run?  It's probably running so often that it runs between every character received by the UART.  You are sending a three-character test message.  After the first two characters are received the main loop performs the check and detects the invalid message.  The main loop sets RX_BUFFER_POS to -1.  But then the third character arrives and increments RX_BUFFER_POS to 0.

After you added the delay to the main loop, perhaps all three characters get received before the main loop performs the check.  If the third character is received before the check then RX_BUFFER_POS will remain equal to -1 and it will appear to work.

When you sent a string of seven characters, I'll assume that it was seven characters followed by "\n".  In this case the main loop checks after every two characters and discards the first six as invalid.  Then the last character is received followed by the "\n" and that passes the check.  I suspect that any odd length string will end with an "OK".  And any even length string will end with RX_BUFFER_POS = to 0 instead of -1 because one extra character is received after the previous check fails.