Skip to content

CLI: Extension commands don't respect quotes in paths with spaces #6487

@dianed-square

Description

@dianed-square

Describe the bug

The CLI doesn't respect quotes when parsing extension commands with spaces. Both goose session --with-extension and goose configure (Add Extension) use the add_extension() function which uses .split_whitespace(), breaking paths like /Applications/IntelliJ IDEA.app/... even when quoted.

Note: The Desktop UI version of this issue is #6417, which is being fixed in #6430.


To Reproduce

Method 1: --with-extension flag

goose session --with-extension '"/Applications/IntelliJ IDEA.app/Contents/jbr/Contents/Home/bin/java" -classpath "/path/with spaces/lib.jar" com.example.Main'

Method 2: goose configure

  1. Run goose configure
  2. Select "Add Extension" → "Command-line Extension"
  3. Enter command: "/Applications/IntelliJ IDEA.app/Contents/jbr/Contents/Home/bin/java" -classpath "/path/with spaces/lib.jar" com.example.Main
  4. Complete the prompts

Result in both cases:

  • Extension fails to start with: Failed to start extension: IO error: No such file or directory (os error 2)
  • Config file shows malformed YAML with quotes embedded incorrectly:
cmd: '"/Applications/IntelliJ'
args:
- IDEA.app/Contents/jbr/Contents/Home/bin/java"
- -classpath
- '"/Applications/IntelliJ'

Expected behavior

Quoted strings should be preserved as single arguments. The CLI already uses shlex::split for other command parsing (e.g., /prompt commands in parse_prompts_command()) - the add_extension() function should use the same approach.


Please provide the following information

  • OS & Arch: macOS
  • Interface: CLI
  • Version: v1.19.1
  • Extensions enabled: N/A (occurs during extension setup)
  • Provider & Model: N/A (configuration issue)

Additional context

Current code (crates/goose-cli/src/session/mod.rs):

pub async fn add_extension(&mut self, extension_command: String) -> Result<()> {
    let mut parts: Vec<&str> = extension_command.split_whitespace().collect();  // ← breaks on all whitespace
    let mut envs = HashMap::new();

    while let Some(part) = parts.first() {
        if !part.contains('=') {
            break;
        }
        let env_part = parts.remove(0);
        let (key, value) = env_part.split_once('=').unwrap();
        envs.insert(key.to_string(), value.to_string());
    }

    if parts.is_empty() {
        return Err(anyhow::anyhow!("No command provided in extension string"));
    }

    let cmd = parts.remove(0).to_string();
    // ... rest of function
}

Suggested fix:

pub async fn add_extension(&mut self, extension_command: String) -> Result<()> {
    // Use shlex to properly handle quoted strings with spaces
    let mut parts: Vec<String> = shlex::split(&extension_command)
        .ok_or_else(|| anyhow::anyhow!("Failed to parse extension command"))?;
    let mut envs = HashMap::new();

    while let Some(part) = parts.first() {
        if !part.contains('=') {
            break;
        }
        let env_part = parts.remove(0);
        let (key, value) = env_part.split_once('=').unwrap();
        envs.insert(key.to_string(), value.to_string());
    }

    if parts.is_empty() {
        return Err(anyhow::anyhow!("No command provided in extension string"));
    }

    let cmd = parts.remove(0);
    // ... rest of function (args is already Vec<String>)
}

Workarounds:

  • Manually edit ~/.config/goose/config.yaml with proper YAML structure:
jb2:
  enabled: true
  cmd: /Applications/IntelliJ IDEA.app/Contents/jbr/Contents/Home/bin/java
  args:
  - -classpath
  - /Applications/IntelliJ IDEA.app/Contents/plugins/mcpserver/lib/mcpserver-frontend.jar:/Applications/IntelliJ IDEA.app/Contents/lib/util-8.jar
  - com.intellij.mcpserver.stdio.McpStdioRunnerKt
  envs:
    IJ_MCP_SERVER_PORT: "64342"
  env_keys:
  - IJ_MCP_SERVER_PORT
  • Create symlinks without spaces (e.g., /Applications/IntelliJIDEA.app)
  • Use wrapper scripts

Related:

Metadata

Metadata

Labels

No labels
No labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions