The script returned an exit code of 0, but output was written to the error output stream

I’ve seen several posts about this issue, as well as this blog post: http://octopusdeploy.com/blog/powershell-exit-codes However…

In my script, I have the following:

@@@
$ErrorActionPreference = “Stop”
$OctopusTreatWarningsAsErrors = “True”

if ($LastExitCode -gt 0) {
throw “Unable to finish installation.”
}
@@@

In the release deployment log I see that Octopus picks up on it:

@@@
2013-06-26 20:26:47 INFO [Deploy Script] ERROR: Unable to finish installation.
2013-06-26 20:26:47 INFO [Deploy Script] ERROR: At C:\Octopus\Applications\DDEV1\Mainline\1.37159.108.0\deploy.ps1:47 char:14
2013-06-26 20:26:47 INFO [Deploy Script] ERROR: + throw <<<< “Unable to finish installation.”
@@@

This is great, but then it flags it as a warning:

@@@
2013-06-26 20:26:47 WARN [Deploy Script] The script returned an exit code of 0, but output was written to the error output stream. Please investigate any errors in the script output above.
2013-06-26 20:26:47 DEBUG Storing a record of the deployment.
@@@

It puzzles me that the deployment isn’t treated as failed and that an error becomes a warning.

What gives? Please help.

Hi,

We’ve gone back and forth on this. Initially we treated any error output as, well, an error, and failed the deployment accordingly. However many people expect their scripts to be able to log errors as errors, and still return 0 as the exit code indicating that the deployment succeeded (with errors).

Since 0 indicates success I think it’s more “correct” for Octopus to go by what the exit code says than by trying to guess the outcome of the script based on what was logged. As a script author it’s then up to you to ensure the correct exit code is returned from your script. I think PowerShell does a bad job of dealing with exit codes for catastrophic failures but that’s unfortunately something we don’t have much control over.

Hope that helps to explain why this works the way it does,

Paul

Thank you, Paul! It makes sense, as also noted in your blog post. And indeed, error handling in Powershell is very inconsistent. Just plain painful.

This is the behavior I was after:

you can use the special Octopus variable OctopusTreatWarningsAsErrors to have Octopus fail the deployment if there’s a warning.

I don’t know why my build wasn’t failing even though there was a warning. Any reason you can think of?

Milan

The tool may be writing output to stderr. The PowerShell team figured that no one would ever be interested in error information, so output written to stderr doesn’t appear in PowerShell output by default.

You could try something like this when calling the external program:

& Something.exe 2>&1 | Out-File C:\MyLog.txt -Append

Hopefully that will give you a better idea of what the error is.

Paul

Thank you, Paul! I’ll give it a try.

In the meantime, the following workaround seems to work:

@@@
if ($? -ne $true) {
Write-Host "Installer failed to execute"
exit -1
}
@@@