Skip to content

EDITOR=C:/Program in Windows Git-Bash #52265

Open

Description

@Roffild

Description

export "EDITOR='C:/Program Files/Notepad++/notepad++.exe' -multiInst -nosession"

/editor in OpenCode TUI return error:

'C:/Program' is not recognized as an internal or external command,
operable program or batch file.

Steps to reproduce

  1. Start Git-Bash in Windows
  2. export "EDITOR='C:/Program Files/Notepad++/notepad++.exe' -multiInst -nosession"
  3. Start OpenCode TUI
  4. /editor

Suggested fix

Bug in

const parts = editor.split(" ")

Environment

  • Windows 10
  • Git-Bash

Activity

  1. added
    needs:complianceThis means the issue will auto-close after 2 hours.
    and removed
    needs:complianceThis means the issue will auto-close after 2 hours.
    on Sep 30, 2026
  2. github-actions commented on Sep 30, 2026

    @github-actions
    Contributor

    Thanks for updating the issue with reproduction steps and system details!

  3. github-actions commented on Sep 30, 2026

    @github-actions
    Contributor

    Thanks for updating the issue with reproduction steps and system details!

  4. Roffild commented on Sep 30, 2026

    @Roffild
    Author

    Google:

    import { parseArgsStringToArgv } from 'string-argv';
    // Или: const { parseArgsStringToArgv } = require('string-argv');
    
    const commandLine = '"C:/Program Files/Notepad++/notepad++.exe" -multiInst -nosession';
    
    const args = parseArgsStringToArgv(commandLine);
    const [executable, ...commandArgs] = args;
    
    console.log('Exec:', executable);
    console.log('Args:', commandArgs);
  5. opencodejr commented on Oct 28, 2026

    @opencodejr
    Contributor

    Thanks for the report and for pointing at the code. I can confirm this.

    I don't have Windows here, so I reproduced it on Linux with the same kind of value: a fake editor at /tmp/opencode/Program Files/Fake Editor/editor.sh and EDITOR="'<that path>' -multiInst -nosession". Running /editor shows Failed to open editor: ENOENT: no such file or directory, posix_spawn ''/tmp/opencode/Program'. The command is split on every space and the quotes aren't handled, so only the part before the first space is run as the program. On Windows that part is passed to cmd, which gives the 'C:/Program' is not recognized... error you saw.

    This happens on 2.2.0 and still happens on the latest dev (86ce19d). The recording and script below show it. /export uses the same code to open the editor, so it should be affected too.

    Related:

    Until it's fixed, pointing EDITOR at a path with no spaces should avoid it, for example a small wrapper script or a symlink to Notepad++.

    recording.mp4

    Screenshot

    Reproduction script (drive.ts)
    // Repro for #52265: $EDITOR with a quoted path containing spaces + arguments
    // breaks /editor, because packages/tui/src/editor.ts splits $EDITOR on " ".
    import { Effect } from "effect"
    import { chmodSync, mkdirSync, writeFileSync } from "node:fs"
    import { OpenCodeDriver } from "opencode-drive"
    
    // A fake "editor" living in a directory whose name contains a space
    // (stands in for "C:/Program Files/Notepad++/notepad++.exe").
    const dir = "/tmp/opencode/Program Files/Fake Editor"
    mkdirSync(dir, { recursive: true })
    writeFileSync(`${dir}/editor.sh`, '#!/bin/sh\nfor f; do last="$f"; done\nprintf "EDITED BY FAKE EDITOR" > "$last"\n')
    chmodSync(`${dir}/editor.sh`, 0o755)
    delete process.env.VISUAL
    process.env.EDITOR = `'${dir}/editor.sh' -multiInst -nosession`
    
    export default OpenCodeDriver.use(
      { ...(process.env.OC_DEV ? { opencode: { dev: process.env.OC_DEV } } : {}), tui: { recording: true } },
      ({ ui }) =>
        Effect.gen(function* () {
          yield* ui.screenshot("01-home")
          yield* ui.type("/editor")
          yield* Effect.sleep("1 second")
          yield* ui.screenshot("02-typed")
          yield* ui.press("return")
          yield* Effect.sleep("4 seconds")
          yield* ui.screenshot("03-after-editor")
          const frame = yield* ui.capture()
          yield* Effect.log(JSON.stringify(frame).slice(0, 4000))
        }),
    )

    Run it with opencode-drive: opencode-drive run ./drive.ts. It drives opencode from your PATH; set OC_DEV to the path of an OpenCode checkout to run that from source instead.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions