Skip to content

fix(powershell): stop create-new-feature.ps1 crashing on a description with no ASCII words - #4138

Open
jawwad-ali wants to merge 1 commit into
github:mainfrom
jawwad-ali:fix/ps-create-feature-null-join
Open

fix(powershell): stop create-new-feature.ps1 crashing on a description with no ASCII words#4138
jawwad-ali wants to merge 1 commit into
github:mainfrom
jawwad-ali:fix/ps-create-feature-null-join

Conversation

@jawwad-ali

Copy link
Copy Markdown
Contributor

Problem

Get-BranchName's fallback branch assumes the pipeline yields at least one element:

$result = ConvertTo-CleanBranchName -Name $Description
$fallbackWords = ($result -split '-') | Where-Object { $_ } | Select-Object -First 3
return [string]::Join('-', $fallbackWords)

ConvertTo-CleanBranchName does $Description.ToLower() -replace '[^a-z0-9\s]', ' ', which blanks every non-ASCII character. So a description written in any non-Latin script leaves nothing for the pipeline to emit:

  • the pipeline yields nothing → $fallbackWords is $null
  • [string]::Join('-', $null) throws ArgumentNullException
  • $ErrorActionPreference = 'Stop' makes it terminating

The script dies with a .NET stack trace, empty stdout, exit 1.

Reproduction on current main (bf88c9f)

All three twins installed into one project, same args, same cwd:

desc = 'добавить авторизацию'
  bash rc=0  BRANCH_NAME='001-'
  py   rc=0  BRANCH_NAME='001-'
  ps   rc=1  Exception calling "Join" with "2" argument(s):
             "Value cannot be null. Parameter name: values"

Identical for 添加用户认证 and '!!! ??? ***'. The bash and Python twins both return an empty suffix and succeed.

This hits every PowerShell user who phrases a feature in their own language — Cyrillic, Han, Kana, Arabic, Greek, Hebrew — plus punctuation-only and accent-only descriptions.

Fix

Wrap the pipeline in @() so it stays an array. Verified at the primitive level:

unwrapped, empty result: type=NULL       Join -> THROWS MethodInvocationException
wrapped   with @():      type=Object[]   Join -> ''        (count=0)
normal case 'a-to-the-of':               Join -> 'a-to-the'   (unchanged)

After the fix, the same three descriptions:

  rc=0  {"BRANCH_NAME":"001-", ...}      x3
  rc=0  {"BRANCH_NAME":"001-user-authentication", ...}   (normal case unchanged)

No breaking change. The only inputs whose behaviour changes are ones that today raise and exit 1. The file stays ASCII-only (verified 0 non-ASCII bytes) so tests/test_ps1_encoding.py::test_ps1_file_is_ascii_only still passes.

Verification

  • Fail-before / pass-after: 3 new-vs-baseline failures with the source reverted → 10 passed, 44 skipped with the fix.
  • Two tests added: a parametrized PS-only crash guard (punctuation / Cyrillic / Han), and a three-way parity test asserting bash, Python and PowerShell all produce 001- for the same input.
  • Scoped regression: no new failures vs a clean-main baseline captured on bf88c9f9.
  • uvx ruff@0.15.0 check src tests → clean

Written with assistance from Claude Code. Bug found, reproduced, and verified by me on current main with real powershell.exe.

…ription

Get-BranchName's fallback assumed the pipeline yields at least one element:

    $fallbackWords = ($result -split '-') | Where-Object { $_ } | ...
    return [string]::Join('-', $fallbackWords)

ConvertTo-CleanBranchName blanks every non-[a-z0-9] character, so a
description written in any non-Latin script leaves nothing for the pipeline
to emit. It yields $null, [string]::Join throws ArgumentNullException, and
$ErrorActionPreference = 'Stop' makes that terminating — the script dies
with a .NET stack trace, empty stdout, exit 1.

Measured with all three twins installed in one project:

  desc='добавить авторизацию'
    bash rc=0 BRANCH_NAME='001-'
    py   rc=0 BRANCH_NAME='001-'
    ps   rc=1 Exception calling "Join" ...

Identical for 添加用户认证 and '!!! ??? ***'. This hits every PowerShell
user who phrases a feature in their own language.

Wrap the pipeline in @() so it stays an array; Join on an empty array
returns "", matching the twins. Verified the normal case is unchanged
('a-to-the-of' -> 'a-to-the', 'add user authentication' ->
'001-user-authentication'), and the file stays ASCII-only (0 non-ASCII
bytes) for tests/test_ps1_encoding.py.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@jawwad-ali
jawwad-ali requested a review from mnriem as a code owner August 15, 2026 14:09
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant