Illegal coercion operation producing inconsistent error/exception behavior depending on scope
00:07 21 Nov 2025

Consider this example, a ps1 script test.ps1

function MyTestFunction
{
    [CmdletBinding()]
    param ()

    try
    {
        [bool]$functionBool= $null
    }
    catch {throw $_}

    Get-Variable 'functionBool'
}

MyTestFunction -ErrorAction Stop

[bool]$scriptBool= $null
  • There are 2x illegal variable declarations in the above example (System.Boolean is a non-nullable type).



Resulting output when this .ps1 script is run by:

  • Dot-sourcing . the script
    Name                           Value
    ----                           -----
    functionBool                   False
    Cannot convert value "" to type "System.Boolean". Boolean parameters accept only Boolean values and numbers, such as $True, $False, 1 or 0.
    At C:\scripts\test.ps1:17 char:1
    + [bool]$scriptBool = $null
    + ~~~~~~~~~~~~~~~~~~~~~~~~~
        + CategoryInfo          : MetadataError: (:) [], ArgumentTransformationMetadataException
        + FullyQualifiedErrorId : RuntimeException
    
    • $functionBool is transformed to $false
      • No exception is thrown
    • $scriptBool is not transformed
      • An (expected) ArgumentTransformationMetadataException exception is thrown

  • Using the call operator &
    Name                           Value
    ----                           -----
    functionBool                   False
    
    • No exception is thrown at all, for either operation.


  • As expected, doing the same operation in the global scope in the CLI throws an exception:

    PS C:\> [bool]$scriptBool = $null
    
    Cannot convert value "" to type "System.Boolean". Boolean parameters accept only Boolean values and
    numbers, such as $True, $False, 1 or 0.
    At line:1 char:1
    + [bool]$scriptBool = $null
    + ~~~~~~~~~~~~~~~~~~~~~~~~~
        + CategoryInfo          : MetadataError: (:) [], ArgumentTransformationMetadataException
        + FullyQualifiedErrorId : RuntimeException
    

Questions

  • What am I not understanding about scopes and PowerShell's behavior in regards to type coercion, specifically the example mentioned at the top?
    • In other words, why doesn't the line [bool]$functionBool= $null throw an exception?
  • If I set a breakpoint on line #8 (where [bool]$functionBool= $null is declared) in VS Code/ISE and step through, program flow will end up in the catch block of the MyTestFunction function.
    • Confusingly, removing the breakpoint produces a different result where the catch{} block is not executed.
powershell type-coercion