Skip to content

spawn start ENOENT error on Windows when adding account #2

@Foadsf

Description

@Foadsf

Description:
When attempting to add an account using gmcli accounts add <email> on Windows, the process crashes with a spawn start ENOENT error. This prevents the automatic browser authorization flow from working.

The issue appears to be that the code attempts to spawn start directly. On Windows, start is a shell built-in command (part of cmd.exe), not a standalone executable, so spawn cannot find it unless run within a shell context.

Steps to Reproduce:

  1. On a Windows machine (Node v22.14.0).
  2. Run gmcli accounts add your.email@gmail.com.
  3. The process crashes immediately with the error below.

Actual Behavior:

Error: spawn start ENOENT
    at ChildProcess._handle.onexit (node:internal/child_process:285:19)
    at onErrorNT (node:internal/child_process:483:16)
    at process.processTicksAndRejections (node:internal/process/task_queues:90:21)
Emitted 'error' event on ChildProcess instance at:
    at ChildProcess._handle.onexit (node:internal/child_process:291:12)
    ...
    errno: -4058,
    code: 'ENOENT',
    syscall: 'spawn start',
    path: 'start',

Environment:

  • OS: Windows
  • Node Version: v22.14.0
  • gmcli Version: 0.1.0

Root Cause:
In src/gmail-oauth-flow.ts, the openBrowser method handles Windows by setting the command to start:

// src/gmail-oauth-flow.ts
private openBrowser(url: string): void {
    const cmd = process.platform === "darwin" ? "open" : process.platform === "win32" ? "start" : "xdg-open";
    spawn(cmd, [url], { detached: true, stdio: "ignore" });
}

Since spawn is called without { shell: true }, Node.js looks for an executable named start.exe or start.cmd, which does not exist.

Suggested Fix:
For Windows, the command should likely be executed via cmd.exe or by enabling the shell option.

Option A (Quick fix):
Change the spawn options to include shell: true (though this has security implications if input isn't sanitized, though here it's just the auth URL).

Option B (Safer Windows specific):

if (process.platform === "win32") {
    spawn("cmd.exe", ["/c", "start", "", url], { detached: true, stdio: "ignore" });
} else {
    // ... existing logic for mac/linux
}

Workaround:
Using the --manual flag works successfully as it bypasses the browser opening logic.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions