Skip to content

Commit 417a9b5

Browse files
docs(skill): add null-clearing enum pattern example to Set template
Gemini round 3 MEDIUM finding: Pitfalls table mentions the [AllowEmptyString] + '' sentinel + translate-to-$null pattern from PR #401, but the Set template doesn't demonstrate it. A user following the template literally would have to assemble the pieces from the pitfalls row. Added a dedicated "SET — null-clearing for enum string parameters" subsection after the basic Set template showing the complete pattern (Set-NBDCIMInterface-style) with: - [AllowEmptyString()] + [ValidateSet(..., '')] - $PSBoundParameters translation loop BEFORE BuildURIComponents - Inline comment explaining why the translation order matters Kept the basic Set template lean since null-clearing is opt-in for specific parameters that need it — not all Set cmdlets do. The [Nullable[bool]] suggestion in round 3 was rejected: the entire repo uses [bool] on Set-* boolean API fields (verified across Set-NBEventRule, Set-NBIPAMAddressRange, Set-NBDCIMDevice, etc.) because BuildURIComponents iterates $PSBoundParameters which only contains user-bound values — unbound [bool] defaults never leak into the PATCH body. See PR comment for the empirical reasoning.
1 parent 801afca commit 417a9b5

1 file changed

Lines changed: 54 additions & 0 deletions

File tree

  • .claude/skills/new-netbox-endpoint

.claude/skills/new-netbox-endpoint/SKILL.md

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -175,6 +175,60 @@ function Set-NB[Module][Resource] {
175175
}
176176
```
177177

178+
#### SET — null-clearing for enum string parameters
179+
180+
When a `Set-*` function's parameter has `[ValidateSet]` and the user needs
181+
to be able to *clear* that field server-side (send JSON `null`), the
182+
`[AllowNull()] [ValidateSet] [string]` combination doesn't work —
183+
PowerShell coerces `$null` to `""` at bind time and then ValidateSet
184+
rejects the empty string (see Pitfalls row 3).
185+
186+
Pattern used on `Set-NBDCIMInterface` (`Duplex`, `POE_Mode`, `POE_Type`,
187+
`RF_Role`, `Mode`) from PR #401 — add `''` to the ValidateSet as a
188+
caller-visible sentinel, use `[AllowEmptyString()]`, then translate `''`
189+
`$null` in `process {}` **before** `BuildURIComponents` so the PATCH
190+
body carries a literal JSON `null`:
191+
192+
```powershell
193+
function Set-NB[Module][Resource] {
194+
[CmdletBinding(SupportsShouldProcess, ConfirmImpact = 'Medium')]
195+
param (
196+
[Parameter(Mandatory, ValueFromPipelineByPropertyName)]
197+
[uint64]$Id,
198+
199+
[AllowEmptyString()]
200+
[ValidateSet('full', 'half', 'auto', '', IgnoreCase = $true)]
201+
[string]$Duplex, # pass '' to clear server-side
202+
203+
[switch]$Raw
204+
)
205+
process {
206+
# Translate '' → $null for the clearable enum params BEFORE
207+
# BuildURIComponents, so the PATCH body becomes {"duplex": null}
208+
# rather than {"duplex": ""} (which NetBox rejects).
209+
$clearable = @('Duplex')
210+
foreach ($p in $clearable) {
211+
if ($PSBoundParameters.ContainsKey($p) -and $PSBoundParameters[$p] -eq '') {
212+
$PSBoundParameters[$p] = $null
213+
}
214+
}
215+
216+
$Segments = [System.Collections.ArrayList]::new(@('<module>', '<resource>', $Id))
217+
$URIComponents = BuildURIComponents -URISegments $Segments.Clone() `
218+
-ParametersDictionary $PSBoundParameters -SkipParameterByName 'Id', 'Raw'
219+
if ($PSCmdlet.ShouldProcess($Id, 'Update <Resource>')) {
220+
InvokeNetboxRequest `
221+
-URI (BuildNewURI -Segments $URIComponents.Segments) `
222+
-Method PATCH -Body $URIComponents.Parameters -Raw:$Raw
223+
}
224+
}
225+
}
226+
```
227+
228+
Numeric parameters needing null-clearing use `[Nullable[T]]` instead —
229+
see Pitfalls row 2 for the `[ValidateRange]` + `[Nullable[int]]` conflict
230+
and PR #398 for the rollout across 9 numeric Interface parameters.
231+
178232
### REMOVE
179233

180234
```powershell

0 commit comments

Comments
 (0)