Repository navigation
[Bug]: Non-Latin feature descriptions produce a nameless branch/directory (001-, 004-, ...) #4574
Description
What happened
A feature description written entirely in a non-Latin script produces a branch and directory with no name at all — just the number and a trailing dash. Every such feature looks identical apart from its number.
specify init demo --integration claude
./.specify/scripts/powershell/create-new-feature.ps1 -Json "给倒推引擎加正推能力"
# {"BRANCH_NAME":"001-", ... "specs\\001-\\spec.md"}
./.specify/scripts/powershell/create-new-feature.ps1 -Json "客户邮件审核队列"
# {"BRANCH_NAME":"004-", ... "specs\\004-\\spec.md"}
Resulting tree — two unrelated features, indistinguishable:
specs/
├── 001-/
├── 004-/
└── 005-mail-review-queue/ # same description, but with -ShortName
For comparison, on the same install:
| Description | BRANCH_NAME |
|---|---|
给倒推引擎加正推能力 |
001- |
add forward scheduling engine |
002-forward-scheduling-engine |
forward 正推 engine |
003-forward-engine (Latin words kept, rest dropped) |
Why this is not the already-known crash
Get-BranchName in create-new-feature.ps1 already carries a comment describing this path — a previous fix stopped it throwing ArgumentNullException and made it return an empty suffix instead, matching the bash and Python twins. That fix is correct as far as it goes: the script no longer dies.
But the outcome it settles on is a directory name that carries no information. The empty suffix is a reasonable internal result; it just isn't a usable name. For a team working in Chinese, Japanese, Korean, Arabic, Hebrew, Thai, Greek, or Cyrillic, this is the default path, not an edge case — every feature they create lands in NNN-.
The root cause is the character class, in two places:
# line 89
$Name.ToLower() -replace '[^a-z0-9]', '-' ...
# line 136
$Description.ToLower() -replace '[^a-z0-9\s]', ' 'Both drop every non-ASCII character, so a CJK description reduces to the empty string before stop-word filtering ever runs.
Suggested directions
Listed roughly by cost; any one of them removes the nameless directory.
- Warn and point at the escape hatch.
-ShortNamealready works (005-mail-review-queueabove). When the computed suffix is empty, print a line saying the description produced no usable branch name and that-ShortName <name>sets one. Cheapest fix, and it turns a silent surprise into a choice. - Fall back to something stable instead of nothing. A short hash or timestamp of the description —
001-f3a9c2,001-20260914— is still opaque, but at least distinct per feature. - Widen the character class. Keep Unicode letters and digits (
\p{L}\p{N}) and percent-encode or transliterate what git cannot take. Git branch names do accept UTF-8, so001-客户邮件审核队列is a legal ref; whether it is desirable is a separate call, and tooling downstream may not all agree.
(1) alone would have saved the confusion here. (3) is the real fix but needs a decision about non-ASCII refs that is yours to make, not mine.
Environment
- specify-cli
1.0.7.dev0(gitd848fb4), installed viauv tool install - Windows 11, PowerShell 5.1, Python 3.13.7, git 2.49.0.windows.1
--scriptauto-selectedpowershell
Not PowerShell-specific — reproduced on both script backends:
specify init demo-sh --integration claude --script sh
bash .specify/scripts/bash/create-new-feature.sh --json "给倒推引擎加正推能力"
# {"BRANCH_NAME":"001-", ... "specs/001-/spec.md"}
Activity
github-actions commentedon Sep 15, 2026
Bug assessment — non-latin-feature-names: Valid · severity low
Bug Assessment: Non-Latin feature descriptions produce nameless branches and directories
Report (summarized)
The reporter observes that descriptions written entirely in non-Latin scripts, such as
给倒推引擎加正推能力and客户邮件审核队列, produce001-/004-branch names andspecs/001-//specs/004-/directories. Latin descriptions retain a useful suffix, while mixed descriptions retain only their Latin words. The behavior is reported for both the PowerShell and Bash script backends on Windows 11 and is distinguished from an earlier PowerShell crash fix: the scripts now complete, but the resulting name is not useful.No additional comments were present on the issue.
Symptom
The feature-number prefix is created successfully, but the generated suffix is empty when the description contains no ASCII letters or digits, so unrelated features can receive indistinguishable names apart from their numeric prefix. The expected behavior is either a usable, stable identifier or an explicit warning/required choice rather than a silent nameless suffix.
Reproduction
create-new-feature.ps1 -Json "给倒推引擎加正推能力".BRANCH_NAMEequal to001-and the correspondingspecs/001-/spec.mdpath.create-new-feature.sh --json "给倒推引擎加正推能力".001-).The issue report states that the behavior is also present for other non-Latin scripts, including Japanese, Korean, Arabic, Hebrew, Thai, Greek, and Cyrillic; those additional scripts were not independently exercised here.
Suspected Code Paths
scripts/powershell/create-new-feature.ps1:86-89—ConvertTo-CleanBranchNamelowercases the value and replaces every character outside[a-z0-9]with-, so a non-Latin-only value cleans to an empty string after separator trimming.scripts/powershell/create-new-feature.ps1:123-136—Get-BranchNameextracts words using[^a-z0-9\s]; descriptions without ASCII words therefore reach the empty fallback.scripts/powershell/create-new-feature.ps1:285-290— the computed suffix is concatenated into${featureNum}-${branchSuffix}, producing the trailing-dash name that is then used forfeatureDir.scripts/bash/create-new-feature.sh:156-159—clean_branch_namehas the equivalent ASCII-only filtering.scripts/bash/create-new-feature.sh:206-217—generate_branch_nameremoves non-ASCII characters before word selection and falls back to the empty cleaned value.scripts/bash/create-new-feature.sh:365-366— the suffix is concatenated into the final branch name and feature directory path.scripts/python/create_new_feature.py:168-175— the Python twin uses the same ASCII-only regular expressions. Existing parity coverage intests/test_create_new_feature_python_parity.py:1218-1240explicitly treats an empty suffix (001-) as the cross-variant behavior, so changing the policy requires updating that contract test.tests/test_create_new_feature_python_parity.py:1218-1240— verifies that punctuation-only and non-Latin descriptions do not crash and currently expects001-; it does not assert that the result is a useful identifier.Root Cause Hypothesis
Confidence: high. All three core implementations intentionally restrict automatic slug generation to ASCII letters and digits. When stop-word filtering finds no usable ASCII words, the fallback applies the same restriction, leaving an empty suffix; the final naming code unconditionally inserts the numeric prefix and separator. The earlier PowerShell fix removed the exception but preserved the empty-name outcome for parity.
Proposed Remediation
Preferred: Define and enforce a non-empty fallback policy in the shared behavior of all three core script variants. The least disruptive option is to detect an empty generated suffix and fail with a clear message directing the user to
--short-name/-ShortName; this prevents creation of ambiguous directories and avoids silently changing branch naming policy. The detection should happen before final directory creation and should have equivalent JSON/error behavior across Bash, PowerShell, and Python.If the project wants fully automatic support, a second preferred-policy decision is needed: either preserve Unicode letters/digits in branch names or generate a deterministic ASCII fallback (for example, a short hash). Unicode preservation is more descriptive but has compatibility implications for downstream tooling; a hash is portable but opaque. Whichever policy is selected must be implemented identically across the three script variants.
Alternatives:
NNN-; this preserves compatibility but does not prevent collisions or confusing directories, so it only improves observability.Files likely to change:
scripts/bash/create-new-feature.shscripts/powershell/create-new-feature.ps1scripts/python/create_new_feature.pytests/test_create_new_feature_python_parity.pytests/test_timestamp_branches.pyand Git extension parity tests if the chosen validation policy is shared with the extension scripts.Tests to add or update:
001-expectation to the chosen contract.Risks & Considerations
--short-namebehavior and document the new fallback/error.Open Questions
--short-namewhen no ASCII slug can be derived?]extensions/gitbranch-creation scripts, which contain parallel slug-generation logic?]github-actions commentedon Sep 17, 2026
The bug assessment for
non-latin-feature-namesis Likely valid, needs reproduction, but the proposed fix is blocked by unresolved policy questions:--short-namewhen no ASCII slug can be derived?extensions/gitbranch-creation scripts?No code change or pull request was made because implementing the fix without those decisions would be guesswork. Please resolve the questions and re-run the assessment/fix stages. The repository does not have a
needs-reproductionlabel, so no status label was added.mnriem commentedon Sep 28, 2026
Filenames should use UTF-8
Fix non-latin-feature-names: preserve Unicode feature names
github-actions commentedon Sep 28, 2026
Pull request created: #4780
github-actions commentedon Sep 28, 2026
Draft PR: main...fix/4574-non-latin-feature-names
non-latin-feature-names: preserve UTF-8 letters and digits in generated branch and feature directory names across Bash, PowerShell, and Python. Please review the draft PR, then validate the fix through the configured stage-3bug-testworkflow.github-actions commentedon Sep 28, 2026
Bug test — non-latin-feature-names: ❌ failing · 5 passed, 2 failed, 0 skipped · fix from PR #4780 (eb4c9dc)
Bug Test Report: Non-Latin feature descriptions produce nameless branches/directories
eb4c9dc662854cd89d713479a0d9e6d887212f92(branchfix/4574-non-latin-feature-names-e406e85dcd5b1c74)timeout 600 python3 -m pytest tests/test_create_new_feature_python_parity.py -q -k 'bash_branch_name_ignores_locale_collation or powershell_preserves_unicode_description or no_ascii_word_description_matches_across_twins'Summary
The proposed Unicode-preserving behavior passes the newly added cross-backend Unicode tests and the focused PowerShell checks, but the focused subset has two failures in the locale-collation cases. Those failures are caused by assertions expecting the unrelated French word
réservationfor Spanish and German descriptions; the implementation instead preserves each input description's Unicode words. The complete parity file also fails 21 tests because existing expectations still require the old ASCII-only output.Test Results
Failures (if any)
test_bash_branch_name_ignores_locale_collation[spanish]— expectedréservationin the branch, received001-añadir-autenticación-usuario.test_bash_branch_name_ignores_locale_collation[german]— expectedréservationin the branch, received001-prüfung-für-benutzer-anlegen.The full parity file run (
100 collected) reported 79 passed and 21 failed. Besides the two focused failures, 19 failures retain pre-fix expectations of001-or ASCII-only sanitization, includingtest_empty_feature_name_warningandtest_all_variants_keep_acronym_next_to_non_ascii.Verification vs. Historical Fix
Not applicable (no historical fix referenced). The issue and proposed PR describe the current fix; no merged historical fix or commit was identified for comparison.
Notes & Caveats
fix: complete Unicode feature naming across script variants
fix: align Unicode categories and UTF-8 feature output
fix: classify Unicode consistently on Bash across locales
[bug-fix] Fix non-latin-feature-names: preserve Unicode feature names (…