CLI crashes (unhandled rejection) when a shell command contains a literal ${} — shell-quote parse throws in classifyShellCommand
Nadie ha tomado este issue todavía.
Evaluación
- Dificultad
- 3/5
- Tiempo estimado
- 1-2 días
- Aptitud para principiantes
- 72/100
- Tipo de issue
- Error
- Claridad
- Bastante claro
- Estado de actividad
- Activo
- Stack tecnológico
- javascript, node.js, shell
Línea de trabajo
Rastrea classifyShellCommand a través de shellPermissionRulesForCommand, getShellPermissionChoices y ShellPermissionPrompt, y luego reproduce el fallo con shell-quote's parse('echo ${}'). Asegúrate de que un comando no analizable ya no finalice la sesión, utilice un comportamiento de aprobación conservador y muestre el error de análisis en el prompt.
Escrito por el modelo de indexación a partir del texto del issue.
Descripción
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.
- Lenguaje dominante
- Sin datos de lenguaje
- Estrellas
- 4k
- Forks
- 350
- Métricas de merge de PR
- Sin PR fusionados en 30 d
Guía de contribución
No hay ninguna guía de contribución indexada para este repositorio
Primeros pasos
- Lee el issue completo y luego la guía de contribución del proyecto.
- Comenta en el issue que vas a ocuparte — evita que dos personas hagan lo mismo.
- Haz un fork del repositorio y trabaja en una rama.
- Abre un pull request que haga referencia al número del issue.
Más de CommandCodeAI/command-code
-
Dificultad 2/5 1-3 horas Aptitud para principiantes 68/100
CommandCodeAI/command-code#855 ·
-
Dificultad 2/5 1-3 horas Aptitud para principiantes 78/100
CommandCodeAI/command-code#841 · 1 comentario ·
-
Dificultad 2/5 1-3 horas Aptitud para principiantes 68/100
CommandCodeAI/command-code#655 · 1 comentario ·
-
Dificultad 2/5 1-3 horas Aptitud para principiantes 68/100
CommandCodeAI/command-code#608 ·
-
Dificultad 3/5 1-2 días Aptitud para principiantes 70/100
CommandCodeAI/command-code#893 ·
Todos los issues de CommandCodeAI/command-code
Issues similares
-
Accept -c in more positions Abiertoarea: compat bug
Dificultad 2/5 1-3 horas Aptitud para principiantes 72/100
-
area: dogs bug priority: P3 silent failure test-code
Dificultad 2/5 1-3 horas Aptitud para principiantes 88/100
-
Dificultad 2/5 1-3 horas Aptitud para principiantes 84/100
phoenixframework/phoenix#6847 ·
-
handle worker groups migrations Abierto
Dificultad 2/5 1-3 horas Aptitud para principiantes 70/100
-
Dificultad 2/5 1-3 horas Aptitud para principiantes 85/100
hust-open-atom-club/hustmirror-cli#52 · 1 comentario ·