Which cmd.exe internal commands clear the ERRORLEVEL to 0 upon success?

This answer is based on experiments I ran under Windows 10. I doubt there are differences with earlier Windows versions that use cmd.exe, but it is possible.

Also note - This answer does not attempt to document the ERRORLEVEL result when an internal command encounters an error (except for a wee bit concerning DEL and ERASE)

Not only are there difference between commands, but a single command can behave differently depending on whether it was run from the command line, or within a batch script with a .bat extension, or from within a batch script with a .cmd extension.

The following set of commands never clear the ERRORLEVEL to 0 upon success, regardless of context, but instead preserve the prior ERRORLEVEL:

  • BREAK
  • CLS
  • ECHO
  • ENDLOCAL
  • FOR : Obviously, commands in the DO clause may set the ERRORLEVEL, but a successful FOR with at least one iteration does not set the ERRORLEVEL to 0 on its own.
  • GOTO
  • IF : Obviously, commands executed by IF may set the ERRORLEVEL, but a successful IF does not set ERRORLEVEL to 0 on its own.
  • KEYS
  • PAUSE
  • POPD
  • RD
  • REM
  • RMDIR
  • SHIFT
  • START
  • TITLE

The next set of commands always clear the ERRORLEVEL to 0 upon success, regardless of context:

  • CD
  • CHDIR
  • COLOR
  • COPY
  • DATE
  • DEL : Always clears ERRORLEVEL, even if the DEL fails (except when run without any file argument).
  • DIR
  • ERASE : Always clears ERRORLEVEL, even if ERASE fails. (except when run without any file argument).
  • MD
  • MKDIR
  • MKLINK
  • MOVE
  • PUSHD
  • REN
  • RENAME
  • SETLOCAL
  • TIME
  • TYPE
  • VER
  • VERIFY
  • VOL

Then there are these commands that do not clear ERRORLEVEL upon success if issued from the command line or within a script with a .bat extension, but do clear the ERRORLEVEL to 0 if issued from a script with a .cmd extension. See https://stackoverflow.com/a/148991/1012053 and https://groups.google.com/forum/#!msg/microsoft.public.win2000.cmdprompt.admin/XHeUq8oe2wk/LIEViGNmkK0J for more info.

  • ASSOC
  • DPATH
  • FTYPE
  • PATH
  • PROMPT
  • SET

Lastly, there are these commands that do not fit neatly into any of the prior categories:

  • CALL : If a :routine or batch script is CALLed, then ERRORLEVEL is exclusively controlled by the CALLed script or :routine. But any other type of successful CALL to a command will always clear ERRORLEVEL to 0 if the CALLed command does not otherwise set it.
    Example: call echo OK.

  • EXIT : If used without /B, then the cmd.exe session terminates and there is no more ERRORLEVEL, just the cmd.exe return code. Obviously EXIT /B 0 clears the ERRORLEVEL to 0, but EXIT /B without a value preserves the prior ERRORLEVEL.

I believe that accounts for all internal commands, unless there is an undocumented command that I missed.


Your description of CALL command is incomplete:

CALL : Clears ERRORLEVEL if the CALLed command does not otherwise set it. Example: call echo OK.

Check this small example:

@echo off

call :setTwo
echo Set two: %errorlevel%

call :preserve
echo Preserve: %errorlevel%

call echo Reset
echo Reset: %errorlevel%

call :subNotExists 2> NUL
echo Sub not exist: %errorlevel%

goto :EOF

:setTwo
exit /B 2

:preserve
echo Preserve
exit /B

Output:

Set two: 2
Preserve
Preserve: 2
Reset
Reset: 0
Sub not exist: 1

CALL description should say something like this:

  • CALL : Clears ERRORLEVEL if the CALLed command does not otherwise set it. Example: call echo OK, but if the called command is a subroutine it preserves the prior ERRORLEVEL. If the called subroutine does not exist, it sets the ERRORLEVEL to 1.