Skip to content

cli: run duplicates the message when passed after -- #57678

Closed

Description

@g1021895463

Description

opencode run duplicates the message when it is passed after --. The new session's first user message contains the text twice. Without --, the message is stored correctly.

I hit this from an automation wrapper that used -- to keep prompts from being parsed as flags.

Related detail: when the message is passed as a single argument containing spaces, the stored text is also wrapped in literal double quotes — with or without --. Both symptoms look like the argument list is being re-serialized somewhere.

Plugins

n/a — reproduced with a plain CLI invocation, no plugins involved.

OpenCode version

2.1.2

Steps to reproduce

  1. Run: opencode run --model / -- DUPREPRO
  2. Read back the created session's first user message: opencode api get /api/session//context
  3. First user message is "DUPREPRO DUPREPRO" — expected "DUPREPRO".

Control, same model and same cwd, only -- removed: opencode run --model / DUPREPRO
First user message is "DUPREPRO" — correct.

Both runs exit 0. Only the stored message differs.

Screenshot

No response

Operating System

Windows 11 (10.0.26300.9457, AMD64)

Terminal

n/a — non-interactive invocation from Git Bash (no TTY)

Activity

  1. opencode-agent commented on Oct 21, 2026

    @opencode-agent
    Contributor

    Thanks for the clear report. I could reproduce this on 2.1.2 and it still happens on the latest dev (4d59657).

    I used a local mock OpenAI-compatible provider that logs the user message it receives:

    • opencode run --model mock/mock DUPREPRO sends "DUPREPRO", which is correct.
    • opencode run --model mock/mock -- DUPREPRO sends "DUPREPRO DUPREPRO", both as the turn message and in the title-generation prompt. The command still exits 0.

    The script below reproduces it. My guess, not yet confirmed, is that the run handler adds the arguments after -- to the message again, even though the argument parser already includes them.

    The second symptom, a single argument with spaces getting wrapped in literal quotes, also reproduces. It's already tracked in #56120.

    Reproduction script (repro.sh)
    #!/usr/bin/env bash
    # Reproduces #57678: `opencode run -- MSG` sends/stores "MSG MSG".
    # Needs bun and @opencode/cli on PATH (bun add -g @opencode/[email protected]).
    # A local OpenAI-compatible mock prints the user message it receives.
    set -euo pipefail
    W=$(mktemp -d /tmp/oc-dup.XXXXXX)
    export HOME="$W/home"; mkdir -p "$HOME/.config/opencode" "$W/proj"
    git init -q "$W/proj"
    
    cat > "$W/mock.ts" <<'EOF'
    Bun.serve({ port: 4555, async fetch(req) {
      if (new URL(req.url).pathname.endsWith("/models")) return Response.json({ data: [{ id: "mock" }] })
      const body = await req.json()
      const last = body.messages.filter((m: any) => m.role === "user").at(-1)
      console.log("USER:", JSON.stringify(last?.content))
      const chunk = (d: any) => `data: ${JSON.stringify({ id: "x", object: "chat.completion.chunk", created: 0, model: "mock", choices: [d] })}\n\n`
      return new Response(chunk({ index: 0, delta: { role: "assistant", content: "ok" } }) + chunk({ index: 0, delta: {}, finish_reason: "stop" }) + "data: [DONE]\n\n",
        { headers: { "content-type": "text/event-stream" } })
    }})
    EOF
    bun "$W/mock.ts" > "$W/mock.log" 2>&1 & MOCK=$!
    trap 'kill $MOCK 2>/dev/null' EXIT
    sleep 1
    
    cat > "$HOME/.config/opencode/opencode.jsonc" <<'EOF'
    { "providers": { "mock": { "package": "@opencode/ai/providers/openai-compatible",
      "settings": { "baseURL": "http://127.0.0.1:4555/v1", "apiKey": "x" },
      "models": { "mock": { "name": "mock" } } } } }
    EOF
    
    cd "$W/proj"
    for args in "DUPREPRO" "-- DUPREPRO"; do
      : > "$W/mock.log"
      opencode run --standalone --format json --model mock/mock $args </dev/null > /dev/null
      echo "== opencode run ... $args"
      grep -av "first message of the conversation" "$W/mock.log" | grep -a USER: | sed 's/^/   /' | head -1
    done
    # Expected: both print USER: "DUPREPRO". Actual: the `--` run prints USER: "DUPREPRO DUPREPRO".

    Run it: bash repro.sh

  2. Ethereal49 commented on Oct 21, 2026

    @Ethereal49

    I’ll trace the run argument handling and fix the duplicate message for the -- case, keeping the separate literal-quote symptom out of scope. I’ll add regression coverage for both invocations with a local mock provider and report the exact verification boundary. Codex is assisting with the investigation and implementation.

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

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions