Summary
PSUseConsistentIndentation incorrectly indents hashtable body content when the hashtable is inside a method call parenthesis (e.g., .Add(@{ ... })). The formatter treats the @{ opening as an additional indentation level relative to the method call position, producing excessive indentation instead of indenting consistently from the line start.
This was originally reported as PowerShell/vscode-powershell#5397, where a maintainer confirmed it belongs in PSScriptAnalyzer. That issue was auto-closed awaiting author feedback.
Steps to Reproduce
# PSScriptAnalyzer 1.24.0 / PowerShell 7.5.4
# Minimal repro - only PSUseConsistentIndentation enabled
$code = @'
$list.Add([PSCustomObject]@{
Name = "Test"
Value = 123
})
'@
$settings = @{
IncludeRules = @("PSUseConsistentIndentation")
Rules = @{
PSUseConsistentIndentation = @{
Enable = $true
IndentationSize = 4
Kind = "space"
}
}
}
Invoke-Formatter -ScriptDefinition $code -Settings $settings
Expected Behavior
Hashtable properties should be indented by one level (4 spaces) from the line start, regardless of where @{ appears on the line:
$list.Add([PSCustomObject]@{
Name = "Test"
Value = 123
})
Actual Behavior
Properties are indented to the @{ column position (8 spaces), and the closing }) gets its own indentation level too:
$list.Add([PSCustomObject]@{
Name = "Test"
Value = 123
})
Additional Test Cases
The problem compounds with deeper nesting:
# Input:
foreach ($item in $items) {
$results.Add([PSCustomObject]@{
Name = $item.Name
Value = $item.Value
Status = "OK"
})
}
# Formatted (actual) - 12 spaces for hashtable body:
foreach ($item in $items) {
$results.Add([PSCustomObject]@{
Name = $item.Name
Value = $item.Value
Status = "OK"
})
}
# Expected - 8 spaces (one level deeper than the foreach body):
foreach ($item in $items) {
$results.Add([PSCustomObject]@{
Name = $item.Name
Value = $item.Value
Status = "OK"
})
}
Standalone hashtables (not inside method calls) format correctly:
# This formats correctly with 4-space indent:
$obj = [PSCustomObject]@{
Name = "Test"
Value = 123
}
Root Cause Analysis
PSUseConsistentIndentation appears to count ( as an indentation-increasing token, then also counts @{ as another level. For standalone hashtables like $x = @{, the = doesn't increase indentation so only @{ counts — producing 4 spaces correctly. But inside .Add(@{, the ( adds one level and @{ adds another, producing 8 spaces (2 × 4).
Impact
This is a common PowerShell pattern — building lists of [PSCustomObject] via .Add() is idiomatic. The excessive indentation forces a choice between:
- Disabling
PSUseConsistentIndentation entirely
- Accepting unintuitively deep indentation
- Disabling
powershell.codeFormatting.alignPropertyValuePairs (which also disables desirable alignment on standalone hashtables)
- Disabling format-on-save for PowerShell files
When combined with PSAlignAssignmentStatement.CheckHashtable, the problem is amplified because value alignment is calculated from the already-wrong base indentation.
Workaround
Setting powershell.codeFormatting.alignPropertyValuePairs: false in VS Code mitigates the worst visual impact but also disables alignment on standalone hashtables where it's desirable.
Environment
- PSScriptAnalyzer: 1.24.0
- PowerShell: 7.5.4
- OS: Linux (also reported on Windows 11 in vscode-powershell#5397)
Summary
PSUseConsistentIndentationincorrectly indents hashtable body content when the hashtable is inside a method call parenthesis (e.g.,.Add(@{ ... })). The formatter treats the@{opening as an additional indentation level relative to the method call position, producing excessive indentation instead of indenting consistently from the line start.This was originally reported as PowerShell/vscode-powershell#5397, where a maintainer confirmed it belongs in PSScriptAnalyzer. That issue was auto-closed awaiting author feedback.
Steps to Reproduce
Expected Behavior
Hashtable properties should be indented by one level (4 spaces) from the line start, regardless of where
@{appears on the line:Actual Behavior
Properties are indented to the
@{column position (8 spaces), and the closing})gets its own indentation level too:Additional Test Cases
The problem compounds with deeper nesting:
Standalone hashtables (not inside method calls) format correctly:
Root Cause Analysis
PSUseConsistentIndentationappears to count(as an indentation-increasing token, then also counts@{as another level. For standalone hashtables like$x = @{, the=doesn't increase indentation so only@{counts — producing 4 spaces correctly. But inside.Add(@{, the(adds one level and@{adds another, producing 8 spaces (2 × 4).Impact
This is a common PowerShell pattern — building lists of
[PSCustomObject]via.Add()is idiomatic. The excessive indentation forces a choice between:PSUseConsistentIndentationentirelypowershell.codeFormatting.alignPropertyValuePairs(which also disables desirable alignment on standalone hashtables)When combined with
PSAlignAssignmentStatement.CheckHashtable, the problem is amplified because value alignment is calculated from the already-wrong base indentation.Workaround
Setting
powershell.codeFormatting.alignPropertyValuePairs: falsein VS Code mitigates the worst visual impact but also disables alignment on standalone hashtables where it's desirable.Environment