Hacktoberfest 2026:维护者为十月标记出来的 issue,仍然开放、适合新手。 浏览 Hacktoberfest issue

[Bug] create-new-feature.sh uses ${word^^} (bash 4+) and silently drops acronyms on macOS (bash 3.2)

未关闭 适合新手
#3,927 2 条评论 0 个 reaction 已指派 0 人 在 GitHub 查看

还没有人认领这个 Issue。

评估

难度
2/5
预计耗时
1-3 小时
新手友好度
84/100
Issue 类型
缺陷
描述清晰度
描述清楚
活跃度
冷清
技术栈
bash
领域
cli, tooling

调研方向

从 .specify/scripts/bash/create-new-feature.sh 约第 231 行开始,检查 acronym branch-name 路径。在 macOS 的 /bin/bash 3.2 下运行提供的 --json --dry-run 命令,并与 Bash 5.x 进行比较。当短的大写 acronym 仍保留在 BRANCH_NAME 中,且 stderr 没有 bad substitution 警告时,即表示完成。

由索引模型根据 Issue 内容生成。

描述

bug-assess invalid

Summary

create-new-feature.sh (line 231) uses ${word^^}, a bash 4+ uppercase expansion. macOS ships bash 3.2.57 (Apple's last GPLv2 build) and the script fails silently on that line: stderr is full of bad substitution warnings, the script keeps running, and the generated branch name silently drops acronyms that were short (≤2 chars) and uppercase in the original description.

Because the script still emits valid JSON and the resulting branch name is plausible, end users on macOS get a quietly truncated branch without realizing it.

Environment

  • macOS (any current version; bash 3.2.57 has been the system bash on every macOS since 2007)
  • Any git repo initialised with specify init
  • No bash from Homebrew installed (or installed but not first in PATH for the running shell)
$ /bin/bash --version
GNU bash, version 3.2.57(1)-release (arm64-apple-darwin24)

$ bash .specify/scripts/bash/create-new-feature.sh --json --dry-run \
    "Transparencia Art. 50 AI Act: aviso de interaccion con IA"
{"BRANCH_NAME":"001-transparencia-art-act", ...}      # ← missing "AI"

$ bash .specify/scripts/bash/create-new-feature.sh --json --dry-run "AI Act transparency"
{"BRANCH_NAME":"001-act-transparency", ...}           # ← missing "AI" (top-3 cutoff also affected)
bad substitution                                         # (only visible in stderr; the JSON looks fine)

The same inputs against bash 5.x preserve the acronym:

$ bash .specify/scripts/bash/create-new-feature.sh --json --dry-run "AI Act transparency"
{"BRANCH_NAME":"001-ai-act-transparency", ...}        # ← "ai" preserved

Root cause

create-new-feature.sh, line 231:

elif echo "$description" | grep -q "\b${word^^}\b"; then
    # Keep short words if they appear as uppercase in original (likely acronyms)
    meaningful_words+=("$word")
fi

${word^^} is case-conversion syntax introduced in bash 4.0 (2009). It is not available in bash 3.2. On bash 3.2 the line errors out, grep runs with the literal placeholder string, the grep returns non-zero, the elif is false, and the short word is silently dropped from meaningful_words[]. The same ${var^^} / ${var,,} pattern likely exists in other vendored scripts; I have not audited them all.

The shebang #!/usr/bin/env bash does not protect against this — env picks whatever bash resolves to in the current PATH, and on a stock macOS that is the system's bash 3.2.

Suggested fix

Two options, in order of preference:

  1. POSIX-portable — replace ${word^^} with a portable uppercase conversion, e.g. echo "$word" | tr '[:lower:]' '[:upper:]', so the script works on bash 3.2 too. This is a one-line change per occurrence and removes the silent failure mode entirely.
  2. Bash 4+ required — if the project decides to require bash 4+ intentionally, make the failure loud: at the top of every vendored script, add a runtime check that fails fast with a clear message and a hint to install bash from Homebrew (brew install bash). Currently the failure is silent and the user has no way to know their branch name is wrong.

I'd recommend option 1 (POSIX-portable) — the function is a small, isolated transformation and the project already has a clean_branch_name that uses tr '[:upper:]' '[:lower:]' to do the inverse. Symmetry argues for replacing the bash-only expansion with tr as well.

Workaround on macOS today

Install bash 5.x via Homebrew and ensure it is first in PATH for the shell that runs Spec-Kit:

brew install bash
# ~/.zshrc or ~/.bashrc, idempotent:
case "$PATH" in
  /opt/homebrew/bin:*) ;;
  /opt/homebrew/bin) ;;
  *) export PATH="/opt/homebrew/bin${PATH:+:$PATH}" ;;
esac

Note that on login shells, /etc/zprofile runs path_helper which re-derives PATH from /etc/paths + /etc/paths.d/* and puts /opt/homebrew/bin at the end — so the prefix must be re-asserted in a file that runs after /etc/zprofile (e.g. ~/.zshrc).

Impact

This affects every macOS developer or agent using Spec-Kit with a description containing acronyms (e.g. "AI Act", "RGPD", "GDPR", "API", "OAuth", "HIPAA", "PCI"). The "feature name" used downstream in specs/NNN-short-name/spec.md is the same truncated string, so the spec file itself also loses the acronym, and any tooling that relies on the branch/spec name to understand the feature (e.g. CI labels, dashboards, search) gets the wrong subject.

Discovered while piloting Spec-Kit on ada-legal-ai (PR #11 in the HOILAB org). Same root cause likely affects any other team running Spec-Kit on macOS.

主要语言
Python
星标
138k
派生
12.4k
平均合并
3 天 6 小时
30 天内合并 PR
145

贡献指南

打开贡献指南

从这里开始

  1. 先读完整个 Issue,再读项目的贡献指南。
  2. 在 Issue 下留言说明你要接手 —— 这能避免两个人做同样的事。
  3. Fork 仓库,在一个分支上完成修改。
  4. 提交 Pull Request,并在描述里引用这个 Issue 编号。

github/spec-kit 的其他 Issue

查看 github/spec-kit 的全部 Issue

相似的 Issue

更多 Python Issue

把新 issue 发到你的邮箱

精选适合新手参与的 GitHub issue 摘要。