AzLocal.UpdateManagement v0.8.77: fix two production strict-mode crashes (Step.05/06/07)#83
Merged
Merged
Conversation
…hes (Step.05/06/07)
Patch release. Both bugs share the same root cause: bare `$obj.Prop` property
access under `Set-StrictMode -Version Latest` THROWS when `Prop` is absent on
a PSCustomObject instead of returning $null. Fixes use the
`$obj.PSObject.Properties['Prop'] -and $obj.Prop` guard idiom (and
`IDictionary.Contains()` for tag bags returned by Invoke-AzRestJson).
Bug 1 - Start-AzLocalClusterUpdate (Step.07 entry):
Production emitted "Error processing cluster '<Name>': The property
'UpdateStartWindow' cannot be found on this object." for clusters whose tag
bag did not include UpdateStartWindow / UpdateExclusionsWindow. The old
`if ($clusterTags -and $clusterTags.$($script:UpdateStartWindowTagName))`
threw before -and could short-circuit because bare .$() member access on a
missing PSCustomObject property is strict-mode-fatal. New code branches on
`$clusterTags -is [System.Collections.IDictionary]` and uses `.Contains()`
for hashtables or `PSObject.Properties[...]` for PSCustomObject tag bags.
Semantic intent ("absent = any time eligible / no window restriction") is
preserved: the outer `if ($windowTagValue -or $exclusionTagValue)` correctly
skips the schedule gate when both are $null.
Bug 2 - Test-AzLocalClusterHealth (Step.05/06 readiness gate):
Production emitted "Checking: <Cluster>... Error: The property
'healthCheckResult' cannot be found on this object." for clusters whose ARM
update summary genuinely had no `healthCheckResult` field (typical for
clusters that have not been probed yet). The catch block then flagged the
cluster HealthState=Error / Passed=$false, and the readiness gate falsely
treated the cluster as blocked, poisoning Step.5 / Step.7 / Step.9 readiness
output. The same pattern was present in Get-HealthCheckFailureSummary
(Private helper) and Get-AzLocalFleetStatusData (Public,
-IncludeHealthDetails). All three sites now use the PSObject.Properties[]
guard; Test-AzLocalClusterHealth correctly classifies such clusters as
HealthState="No Data" / Passed=$true and continues.
Tests: two new Pester regression contexts feed the minimal real-world
property-less shapes and assert Should -Not -Throw plus the correct downstream
classification. Both bugs were invisible to parse-time analysis - only runtime
against the property-less shape triggers the strict-mode throw.
GENERATED_AGAINST_MODULE_VERSION bumped from 0.8.76 to 0.8.77 across all 22
bundled pipeline templates (github-actions + azure-devops).
Pester: 1142 passed / 0 failed / 1 skipped.
No public API change or new exports (still 60).
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Patch release. Fixes two production strict-mode crashes that surfaced in Step.05 / Step.06 / Step.07 of the bundled apply-updates pipelines. Both bugs share the same root cause: bare
$obj.Propproperty access underSet-StrictMode -Version Latestthrows whenPropis absent on aPSCustomObjectinstead of returning$null.Resolves no open issue (regressions found by live customer production traces, not filed).
What changed
Bug 1 -
Start-AzLocalClusterUpdate(Step.07 main entry)Production emitted
Error processing cluster '<Name>': The property 'UpdateStartWindow' cannot be found on this object.for clusters whose tag bag did not includeUpdateStartWindow/UpdateExclusionsWindow. The oldif ($clusterTags -and $clusterTags.$($script:UpdateStartWindowTagName))threw before-andshort-circuited because bare.$()member access on a missingPSCustomObjectproperty is strict-mode-fatal.Fix: branch on
$clusterTags -is [System.Collections.IDictionary]and use.Contains()for hashtables /PSObject.Properties[...]forPSCustomObjecttag bags. The semantic intent ("absent = any time eligible / no window restriction") is preserved: the outerif ($windowTagValue -or $exclusionTagValue)correctly skips the schedule gate when both are$null.Bug 2 -
Test-AzLocalClusterHealth(Step.05/06 readiness gate)Production emitted
Checking: <Cluster>... Error: The property 'healthCheckResult' cannot be found on this object.for clusters whose ARM update summary genuinely had nohealthCheckResultfield (typical for clusters not yet probed). Thecatchblock then flagged the clusterHealthState=Error / Passed=$false, and the readiness gate falsely treated it as blocked, poisoning Step.5 / Step.7 / Step.9 readiness output. The same bare-access pattern was present inGet-HealthCheckFailureSummary(Private helper) andGet-AzLocalFleetStatusData(Public,-IncludeHealthDetails).Fix: all three sites now use the
PSObject.Properties[...]guard;Test-AzLocalClusterHealthcorrectly classifies such clusters asHealthState="No Data" / Passed=$trueand continues.Tests
Two new Pester regression contexts feed the minimal real-world property-less shapes and assert
Should -Not -Throwplus the correct downstream classification. Both bugs were invisible to parse-time analysis - only runtime against the property-less shape triggers the strict-mode throw.Pipeline templates
GENERATED_AGAINST_MODULE_VERSIONbumped from'0.8.76'to'0.8.77'across all 22 bundled pipeline templates (11 github-actions + 11 azure-devops).API surface
No public API change or new exports (still 60).
See CHANGELOG.md for the full v0.8.77 entry.