How to stop Windows command interpreter from quitting batch file execution on an incorrect user input?

If I have the following example code:

@echo off
:menu
cls
echo 1. win
echo 2. lose
set /p menu=
goto %menu%
pause>nul

:win
cls
echo yay lolz
pause>nul

:lose
cls
echo really?
pause>nul

How do I stop the batch from quitting if I type "test" instead of a valid response?


First, I suggest to bookmark in your browser:

  • Microsoft's command-line reference
  • An A-Z Index of the Windows CMD command line (SS64)

You can get help for every Windows command by running in a command prompt window the command with /? as parameter, for example if /?, set /?, ...


Second, don't use set /p if the user should choose one of several options. There are multiple facts which must be taken into account on prompting user for entering a string and assigning it to an environment variable:

  1. On usage of set /P "MyVar=Your choice: " the environment variable MyVar is not modified if the user presses intentionally or by mistake just RETURN or ENTER. This means if the environment variable MyVar is not defined already before the user prompt, it is still not defined after user prompt finished with just hitting key RETURN. And if MyVar is defined already before user prompt, it keeps its value unmodified in case of user presses just RETURN or ENTER.

  2. The user has the freedom to type any string on being prompted with set /P. The batch file writer has no control on what the user really enters. So the batch file writer must take into account that the user enters by mistake or intentionally a string which could result in an exit of batch file execution because of a syntax error, or it does something completely different as it is defined for.

A simple example:

@echo on
:MainMenu
@set /P "menu=Your choice: "
if %menu% == 1 goto Label1
if %menu% == 2 goto Label2
goto MainMenu

:Label1
@echo Option 1 was chosen, fine.
goto :EOF

:Label2
@echo Option 2 was chosen, okay.

This batch file with echo on instead of echo off at top is started from within a command prompt window for debugging purposes.

Just RETURN is pressed on user prompt on first run. Windows command interpreter exits batch processing because first IF condition is preprocessed before execution of IF command to:

if  == 1 goto Label1

There is obviously missing the first argument. cmd.exe encounters this syntax error and exits batch processing with an appropriate error message. The reason is the missing definition of environment variable menu which is not defined before user prompt and is still not defined after user prompt.

The string 2 is entered on second run of the batch file from within command prompt window and the batch file works as expected.

On third run of the batch file from within same command prompt window again just RETURN is pressed on user prompt. The batch file outputs again the second message. Why? The environment variable menu is still defined from second batch file execution with that string and the variable was not modified on pressing RETURN.

Okay, let us modify the example batch file to:

@echo on
:MainMenu
@set "menu=2"
@set /P "menu=Your choice: "
if "%menu%" == "1" goto Label1
if "%menu%" == "2" goto Label2
goto MainMenu

:Label1
@echo Option 1 was chosen, fine.
goto :EOF

:Label2
@echo Option 2 was chosen, okay.

This is already better as now environment variable menu is always predefined with value 2. So if the user enters nothing, a jump to Label2 is done. Also the value of previous run of variable menu has no effect anymore on execution of batch file.

But is that really secure and fail safe now?

No, it isn't. The user still can enter by mistake a wrong string.

For example the user enters by mistake " instead of 2 which is easy on German keyboards as CapsLock+2 or Shift+2 results in entering ". The first IF command line after preprocessing is now:

if """ == "1" goto Label1

And this is again an invalid command line resulting in an exit of batch file processing because of a syntax error.

Let us assume a user enters on prompt the string:

" == "" call dir "%USERPROFILE%\Desktop" & rem 

Note: There is a space at end.

The first IF condition is preprocessed by Windows command interpreter to:

if "" == "" call dir "%USERPROFILE%\Desktop"   & rem " == "1" goto Label1

It can be seen that the batch files executes now a command not written in the batch file at all on both IF conditions.

How to get a user prompt fail safe and secure?

By using delayed environment variable expansion at least around code evaluating the user input string.

@echo on
:MainMenu
@setlocal EnableDelayedExpansion
@set "menu=2"
@set "Label=MainMenu"
@set /P "menu=Your choice: "
if "!menu!" == "1" set "Label=Label1"
if "!menu!" == "2" set "Label=Label2"
endlocal & goto %Label%

:Label1
@echo Option 1 was chosen, fine.
goto :EOF

:Label2
@echo Option 2 was chosen, okay.

Now the user input string does not modify anymore the command lines executed by Windows command interpreter. So an exit of batch file processing because of a syntax error caused by user input is not possible anymore. And the batch file never executes commands not written in batch file.


Third, there is a better command than set /P for a simple choice menu – CHOICE.

@echo off
:MainMenu
cls
echo/
echo    1 ... Option 1
echo    2 ... Option 2
echo    E ... Exit
echo/
%SystemRoot%\System32\choice.exe /C 12E /N /M "Your choice: "
if errorlevel 3 goto :EOF
if errorlevel 2 goto Label2
if not errorlevel 1 goto MainMenu

@echo Option 1 was chosen, fine.
goto :EOF

:Label2
@echo Option 2 was chosen, okay.

The user has no freedom anymore to enter something not defined by batch file writer. The batch file continues immediately after the user has pressed either 1, 2, e or Shift+E. Everything else is ignored by choice with exception of Ctrl+C.

The dynamic variable ERRORLEVEL has with three options nearly always a value in range 1 to 3 after choice terminated with returning 1 to 3 as exit code to calling cmd.exe. The exception is the rare use case that the user of a batch file pressed Ctrl+C on prompt and answers the next prompt Terminate batch job (Y/N)? of cmd.exe with N. In this case the dynamic variable ERRORLEVEL has the value 0 which is the reason for if not errorlevel 1 goto MainMenu to handle also this very special use case.

Note: if errorlevel X means IF GREATER OR EQUAL X. So it is always necessary to start with highest possible exit code of command choice.

As the exit code assigned to ERRORLEVEL is well known, it is possible on larger menus to optimize the code further by using appropriate labels:

@echo off
:MainMenu
cls
echo/
echo    1 ... Option 1
echo    2 ... Option 2
echo    E ... Exit
echo/
%SystemRoot%\System32\choice.exe /C 12E /N /M "Your choice: "
goto Label%ERRORLEVEL%

:Label0
rem The user pressed Ctrl+C and on next prompt N and
rem so made no choice. Prompt the user once again.
goto MainMenu

:Label1
@echo Option 1 was chosen, fine.
goto :EOF

:Label2
@echo Option 2 was chosen, okay.
goto :EOF

:Label3

The usage of command CHOICE can make choice menus very simple to code.

See also: How can I make an "are you sure" prompt in a Windows batch file?


Fourth, see also my answer on Where does GOTO :EOF return to?