Skip to content

[Bug] Project actions menu: Auto-discover dev server runs the first saved action instead of discovering a server #5293

Closed

Description

@sogeisetsu

Steps to reproduce

  1. Windows desktop app 2.4.0, open a project that has saved project actions (any action whose command is a plain shell command).
  2. In the session header, open the project-actions dropdown (the one with "Add new action" / "添加新操作").
  3. Click Auto-discover dev server ("自动发现开发服务器") — a synthetic item at the bottom of that menu, not one of the saved actions.
  4. A terminal tab opens, labelled "Auto-discover dev server", and it runs the first saved project action's command.

In my case the first saved action is a PowerShell command that shells out to gh workflow run update-daily-report.yml --ref main. Clicking the discover item printed:

✓ Created workflow_dispatch event for update-daily-report.yml at main
https://github.com/.../actions/runs/39423716119

and actually started a GitHub Actions run. It was 100% reproducible: every click on the discover item runs that action, never anything related to dev-server discovery.

What you expected

Clicking "Auto-discover dev server" either finds/starts a dev server or shows a preview of one — it should never execute one of the project's saved actions.

What happened instead

The first saved project action was executed in a terminal tab that is labelled as the dev-server discovery item. The tab title and its content disagree, and a real workflow got triggered by a click that had nothing to do with it.

Where does it happen?

Desktop app (Windows)

OpenChamber version

2.4.0

OpenCode version and model/provider (if relevant)

opencode 2.0.32 (bundled CLI), no model involved

Screenshots / recordings (optional)

The terminal tab is titled "自动发现开发服务器" while showing the gh workflow run output of the first saved action.

Logs (optional)

Bundle evidence, resources/web-dist/assets/main-*.js: the discovery item is synthetic and has no command of its own —

Ie = useMemo(() => ({
  id: "__openchamber_auto_discover_preview__",
  name: t("projectActions.actions.autoDiscover"),
  command: "",
  icon: "scan-2",
  autoOpenUrl: true
}), [t]),
Pe = we ? [...A, Ie] : A

It is appended after the saved actions and then goes through the same select/trust/run path as a real action, so with an empty command the run resolves to the first saved action (index 0). Adding a second saved action did not change the outcome — the first one still runs. This project currently has two saved actions: a daily-report workflow trigger and a summary workflow trigger.

Activity

  1. openchamber-bot commented on Oct 20, 2026

    @openchamber-bot
    Contributor

    For the maintainer: fix-ready — cause traced

    The reporter's conclusion is right — the discover item runs a saved action's command — but not their mechanism: the empty command never reaches the terminal. Clicking the item runs discovery (packages/ui/src/components/layout/useProjectActionsRunner.ts:763-782), which calls detectDevServerCommand (packages/ui/src/lib/detectDevServer.ts:32). Its first step, findDevServerAction (detectDevServer.ts:100-116), treats the first saved action whose lowercased name + command merely contains dev, start, preview, or serve — bare substrings, no word boundary (detectDevServer.ts:22-27, 106-108) — as "the dev server" and returns its command, which then executes in the tab labelled "Auto-discover dev server" (useProjectActionsRunner.ts:776, 848-851). This is the only code path by which auto-discover ever executes a saved action, so the mechanism is confirmed for the symptom; the specific substring that matched in the reporter's action (a PowerShell wrapper plausibly contains Start-Process/Start-Job → "start", or the action's name does) is plausible-but-unconfirmed since their exact name/command isn't visible here.

    Reusing a dev-like saved action for discovery is deliberate (#2743 describes exactly this detection), but a bare substring check lets start inside Start-Process or prose match, and the run executes with real side effects and no confirmation. Directions are yours: word-boundary/anchored matching, preferring package.json scripts, or confirming before running a guessed action.

    Code path
    1. ProjectActionsButton.tsx:97-104 — a dropdown item click calls runner.select + runner.toggle; runner.actions includes the synthetic discover item (useProjectActionsRunner.ts:399-413).
    2. useProjectActionsRunner.ts:763-782 — action.id === AUTO_DISCOVER_ACTION_ID → fetch saved actions + package.json scripts, call detectDevServerCommand.
    3. detectDevServer.ts:40-48 — findDevServerAction runs first; on a match its command becomes the "discovered dev server".
    4. detectDevServer.ts:100-116 — first action whose name + command includes any of dev/start/preview/serve wins; no word boundary, first match, index order — matching "always the first saved action".
    5. useProjectActionsRunner.ts:787-851 — the returned command is normalized and executed in a terminal tab labelled with the discover item's name; package.json and static-site fallbacks are never consulted once an action "matches".

    If you paste the exact name and command of your first saved action, the matched substring can be confirmed.

  2. added
    bugSomething isn't working
    area:terminalIntegrated terminal, PTY, xterm
    root-cause:foundBot traced a concrete code-level cause (not yet confirmed by the reporter)
    on Oct 20, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

area:terminalIntegrated terminal, PTY, xtermbugSomething isn't workingplatform:windowsWindows desktop / WSLroot-cause:foundBot traced a concrete code-level cause (not yet confirmed by the reporter)

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions