CLI crashes (unhandled rejection) when a shell command contains a literal ${} — shell-quote parse throws in classifyShellCommand
还没有人认领这个 Issue。
评估
- 难度
- 3/5
- 预计耗时
- 1-2 天
- 新手友好度
- 72/100
- Issue 类型
- 缺陷
- 描述清晰度
- 基本清楚
- 活跃度
- 活跃
- 技术栈
- javascript, node.js, shell
调研方向
跟踪 classifyShellCommand 经过 shellPermissionRulesForCommand、getShellPermissionChoices 和 ShellPermissionPrompt,然后使用 shell-quote's parse('echo ${}') 重现该故障。确保无法解析的命令不再结束会话,采用保守的批准行为,并在提示中显示解析错误。
由索引模型根据 Issue 内容生成。
描述
Summary
The CLI dies with an unhandled promise rejection when it builds the shell-permission prompt for a command whose text contains a literal ${}. shell-quote's parse() throws Bad substitution: ${}, and classifyShellCommand → shellPermissionRulesForCommand → getShellPermissionChoices → ShellPermissionPrompt does not catch it, so the whole session exits.
This is not a "bad command" problem: the command is never run, and the user never sees a prompt. The process is gone, and with it the conversation context of a long-running session.
Environment
| command-code | 1.54.1 |
| node | v24.1.0 |
| OS | macOS 27.0, arm64 (Apple Silicon, Homebrew install at /opt/homebrew) |
| shell-quote (bundled) | 1.10.0 |
| Session | running inside tmux, driven by an automation harness (messages sent programmatically), auto-yes enabled |
Stack trace (as printed)
✖ CRITICAL: Unhandled Promise Rejection!
✖ ERROR → Error
ℹ REASON → Bad substitution: ${}
ℹ ERROR STACK ↓
Error: Bad substitution: ${}
at parseEnvVar (/opt/homebrew/lib/node_modules/command-code/node_modules/shell-quote/parse.js:157:12)
at /opt/homebrew/lib/node_modules/command-code/node_modules/shell-quote/parse.js:236:14
at Array.map (<anonymous>)
at parseInternal (/opt/homebrew/lib/node_modules/command-code/node_modules/shell-quote/parse.js:113:17)
at parse (/opt/homebrew/lib/node_modules/command-code/node_modules/shell-quote/parse.js:309:15)
at classify (file:///opt/homebrew/lib/node_modules/command-code/dist/cli.mjs:2:382298)
at classifyShellCommand (file:///opt/homebrew/lib/node_modules/command-code/dist/cli.mjs:2:383445)
at shellPermissionRulesForCommand (file:///opt/homebrew/lib/node_modules/command-code/dist/cli.mjs:2:1075519)
at getShellPermissionChoices (file:///opt/homebrew/lib/node_modules/command-code/dist/cli.mjs:2:1083719)
at ShellPermissionPrompt (file:///opt/homebrew/lib/node_modules/command-code/dist/cli.mjs:16:21387)
ℹ Trace ID: 2bf510fd5bd624f90b2282f692816b84
Minimal repro of the throwing dependency
shell-quote throws on a literal ${} (empty substitution), while every other ${...} form parses fine:
const { parse } = require('shell-quote'); // 1.10.0
parse('echo ${VAR}'); // ok
parse('echo ${#a[@]}'); // ok
parse('echo ${PIPESTATUS[0]}');// ok
parse('echo ${!v}'); // ok
parse('echo $(( 1 + 2 ))'); // ok
parse('echo ${}'); // throws: Bad substitution: ${}
parse('echo "${}"'); // throws: Bad substitution: ${}
parse('printf %s ${}'); // throws: Bad substitution: ${}
Source: shell-quote/parse.js parseEnvVar() throws when ${ is immediately followed by }.
How it happens in practice
The model writes a shell command whose text happens to contain ${} — for example when echoing or heredoc-ing documentation/templates that mention ${} literally, or when a variable name is interpolated into an empty string while composing the command. The CLI then tries to classify that command for the permission prompt and crashes before showing anything.
Expected behaviour
Classification of a command that cannot be parsed should degrade, not kill the process. Something like:
- wrap the
shell-quoteparse()call intry/catchinsideclassify/classifyShellCommand, - on a parse error, fall back to the most conservative classification (treat the command as unrecognised and require explicit approval), and
- surface the parse error in the prompt instead of throwing.
A global unhandledRejection guard around the prompt path would also prevent a single classification bug from ending the session.
Impact
- The CLI exits mid-run. In an orchestrated, multi-session setup the managing session dies and its conversation context is lost; recovery has to be done by hand from the run artifacts.
- Because the crash is in the permission prompt path,
--trust/ auto-yes settings do not help: the process dies while building the prompt.
- 主要语言
- 没有语言数据
- 星标
- 4k
- 派生
- 350
- PR 合并指标
- 30 天内没有已合并 PR
贡献指南
这个仓库没有索引到贡献指南
从这里开始
- 先读完整个 Issue,再读项目的贡献指南。
- 在 Issue 下留言说明你要接手 —— 这能避免两个人做同样的事。
- Fork 仓库,在一个分支上完成修改。
- 提交 Pull Request,并在描述里引用这个 Issue 编号。
CommandCodeAI/command-code 的其他 Issue
-
难度 2/5 1-3 小时 新手友好度 68/100
CommandCodeAI/command-code#855 ·
-
难度 2/5 1-3 小时 新手友好度 78/100
CommandCodeAI/command-code#841 · 1 条评论 ·
-
难度 2/5 1-3 小时 新手友好度 68/100
CommandCodeAI/command-code#655 · 1 条评论 ·
-
难度 2/5 1-3 小时 新手友好度 68/100
CommandCodeAI/command-code#608 ·
-
难度 3/5 1-2 天 新手友好度 70/100
CommandCodeAI/command-code#893 ·
查看 CommandCodeAI/command-code 的全部 Issue
相似的 Issue
-
难度 2/5 1-3 小时 新手友好度 85/100
hust-open-atom-club/hustmirror-cli#52 · 1 条评论 ·
-
难度 2/5 1-3 小时 新手友好度 65/100
qgis/QGIS-Documentation#11275 ·
-
难度 1/5 1 小时以内 新手友好度 92/100
milvus-io/birdwatcher#545 ·
-
难度 2/5 1-3 小时 新手友好度 88/100
-
enhancement
难度 2/5 1-3 小时 新手友好度 68/100
JuliusBrussee/caveman#1102 · 1 条评论 ·