From 2bc74a06c7c8f4fab5cc6e22e561372192b9faba Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sun, 22 Feb 2026 09:49:10 +0000 Subject: [PATCH 1/3] Initial plan From 23bfd78574cc34253c1b5e552875cdcfed4dd4ec Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sun, 22 Feb 2026 09:56:37 +0000 Subject: [PATCH 2/3] Fix null attribute value binding error in Invoke-IdleProviderMethod Co-authored-by: blindzero <13959569+blindzero@users.noreply.github.com> --- .../Public/Invoke-IdleProviderMethod.ps1 | 1 + .../Invoke-IdleStepEnsureAttributes.Tests.ps1 | 32 +++++++++++++++++++ 2 files changed, 33 insertions(+) diff --git a/src/IdLE.Core/Public/Invoke-IdleProviderMethod.ps1 b/src/IdLE.Core/Public/Invoke-IdleProviderMethod.ps1 index 11540f7c..911ccca6 100644 --- a/src/IdLE.Core/Public/Invoke-IdleProviderMethod.ps1 +++ b/src/IdLE.Core/Public/Invoke-IdleProviderMethod.ps1 @@ -66,6 +66,7 @@ function Invoke-IdleProviderMethod { [string] $MethodName, [Parameter(Mandatory)] + [AllowNull()] [AllowEmptyCollection()] [object[]] $MethodArguments ) diff --git a/tests/Steps/Invoke-IdleStepEnsureAttributes.Tests.ps1 b/tests/Steps/Invoke-IdleStepEnsureAttributes.Tests.ps1 index 50ec784d..636b7aba 100644 --- a/tests/Steps/Invoke-IdleStepEnsureAttributes.Tests.ps1 +++ b/tests/Steps/Invoke-IdleStepEnsureAttributes.Tests.ps1 @@ -322,6 +322,38 @@ Describe 'Invoke-IdleStepEnsureAttributes (built-in step)' { $attributeNames | Should -Contain 'Title' $attributeNames | Should -Contain 'Office' } + + It 'passes $null attribute values without error (regression: MethodArguments binding)' { + # When attributes contain $null values (e.g., to unset/clear an attribute), + # Invoke-IdleProviderMethod must not fail with "Cannot bind argument to parameter + # 'MethodArguments' because it is null." - caused by PS binding an [object[]] + # containing $null elements to a [Mandatory] parameter without [AllowNull()]. + $step = [pscustomobject]@{ + Name = 'Unset phone attributes' + Type = 'IdLE.Step.EnsureAttributes' + With = @{ + Provider = 'Identity' + IdentityKey = 'user@contoso.com' + Attributes = @{ + mobile = $null + telephoneNumber = $null + } + } + } + + $handler = 'IdLE.Steps.Common\Invoke-IdleStepEnsureAttributes' + { & $handler -Context $script:Context -Step $step } | Should -Not -Throw + + # Both attributes should have been called with $null value + $callsByName = @{} + $script:FakeProviderLegacy.CallLog | ForEach-Object { + $callsByName[$_.Name] = $_ + } + $callsByName.Keys | Should -Contain 'mobile' + $callsByName.Keys | Should -Contain 'telephoneNumber' + $callsByName['mobile'].Value | Should -BeNullOrEmpty + $callsByName['telephoneNumber'].Value | Should -BeNullOrEmpty + } } Context 'StepResult shape' { From 628767e37af51fb3464f88fd928b24128cea5666 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sun, 22 Feb 2026 10:04:56 +0000 Subject: [PATCH 3/3] Add null-reference guard to Invoke-IdleProviderMethod after AllowNull fix Co-authored-by: blindzero <13959569+blindzero@users.noreply.github.com> --- src/IdLE.Core/Public/Invoke-IdleProviderMethod.ps1 | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/IdLE.Core/Public/Invoke-IdleProviderMethod.ps1 b/src/IdLE.Core/Public/Invoke-IdleProviderMethod.ps1 index 911ccca6..1dbd3947 100644 --- a/src/IdLE.Core/Public/Invoke-IdleProviderMethod.ps1 +++ b/src/IdLE.Core/Public/Invoke-IdleProviderMethod.ps1 @@ -73,7 +73,14 @@ function Invoke-IdleProviderMethod { # Auth session acquisition (optional, data-only) $authSession = $null - + + # [AllowNull()] on $MethodArguments is required so PowerShell's parameter binder accepts + # [object[]] arrays that contain $null elements (e.g., a $null attribute value to clear). + # However, the array reference itself must never be null - that would indicate a caller bug. + if ($null -eq $MethodArguments) { + throw "MethodArguments must not be null. Pass an empty array if no arguments are needed." + } + # Validate AuthSessionOptions early (regardless of broker availability) if ($With.ContainsKey('AuthSessionOptions')) { $sessionOptions = $With.AuthSessionOptions