I have some issues with the New-PSUApiResponse. I have done many tests for debugging and my conclusion is:
When an error comes from a function in a try{} block then the catch{} block will do something strange with New-PSUApiResponse. Then it is always Error 400 Badrequest without any output.
For example:
This is an error from ConvertFrom-Json for example with a wrong body format. Where Left is my code and right the result.
$body = '{"sizeGb"= 200}' # Wrong JSON format to test error

This is an error in try{} block itself for example. Where left is also my code and right the result.

I expect that the second example always works with any error from any function.
I hope this is clear enough
Hi Romano,
Thank you for the clear examples and screenshots.
We ran your code on PowerShell Universal 2026.3.3 in our lab, endpoint at default settings, with your malformed body {"sizeGb"= 200}. The caught ConvertFrom-Json error returned your own 400 response:
{
"Error": "Failed to parse JSON body",
"Message": "Conversion from JSON failed with error: Invalid character after parsing property name. Expected ':' but got: =. Path '', line 1, position 9."
}
A caught Get-Item error and a throw inside try{} came back the same way, as did your divide-by-zero example. So in our lab, New-PSUApiResponse in the catch{} block works for errors from cmdlets too. In your ConvertFrom-Json screenshot the response has Content-Type application/json and RawContentLength 0, which none of our tests produced, so your setup differs from ours somewhere.
To find what it is, could you send us:
1. Your PowerShell Universal version, operating system, installation type (Windows service, IIS or Docker) and the environment your APIs run in (PowerShell 7 or Windows PowerShell 5.1).
2. The complete endpoint: its New-PSUEndpoint line with all parameters (such as -Environment or -ErrorAction) and the whole script block, or the .ps1 file it points to with -Path.
3. The command you use to call the endpoint, including any content type or headers.
Side note, once you have collected these: New-PSUApiResponse answered text/plain in our tests because the call sets no content type; add -ContentType 'application/json' to return your payload as JSON: https://docs.devolutions.net/powershell-universal/cmdlets/New-PSUApiResponse/
Best regards,
Michel
Michel Audi
Hi Michel,
Thank you for your response!
Your reaction triggered me to test something more. What I have noticed is that it does not work when the API is created from a PSU module, but it does work when the API is created directly from the PSU admin console.
I am running PSU (2026.3.3) on my dev seat which is Windows 11 and running PSU directly from a powershell 7 process. So the api's are running both in PowerShell 7 environment.
For this further test i created my endpoint like this:
$endpointParams = @{
Url = '/api/v1/test/apiresponse'
Description = 'API for testing API Responses with errors.'
Method = @('GET')
Module = 'psu.test'
Command = 'Invoke-APITestAPIResponse'
Environment = 'PowerShell 7'
Tag = @('test')
Documentation = 'TEST'
}
New-PSUEndpoint @endpointParams
I do a simple Invoke-Webrequest without extra parameters for this test.
Hi Romano,
Thank you, the module was the missing piece. We reproduced it on PowerShell Universal 2026.3.3 in our lab.
An endpoint created with -Module and -Command, at its default settings, answered your ConvertFrom-Json test with a 400, Content-Type application/json and an empty body, as in your screenshot. Your divide-by-zero test returned your own response, and the same ConvertFrom-Json code as a script endpoint did too. When PowerShell Universal runs a module command for an endpoint, the ConvertFrom-Json error is still counted as an endpoint error even though your catch{} block handled it, and with the endpoint's default error action (Stop) PowerShell Universal then answers with its own 400 instead of your New-PSUApiResponse.
The workaround is to add -ErrorAction Continue to the endpoint definition, as in this line.
New-PSUEndpoint @endpointParams -ErrorAction Continue
With a parameter set like yours, including Environment = 'PowerShell 7', your ConvertFrom-Json test then returned your own 400 with your JSON message. Keep in mind that with this setting, an error your code writes without stopping (Write-Error, for example) no longer turns the response into an error, so the endpoint returns what your function returns (a 200 in our test). An uncaught error that stops your function still came back as a 400 with its message.
I have documented this behaviour for our development team's review.
Best regards,
Michel
Michel Audi