Skip to content

app: hamburger menu shows message templates ({{path}}/{{error}}) instead of item labels #61252

Open

Description

@askvittorio

Summary

The desktop app's hamburger menu (top-left) and its "CLI telepítése…" submenu render message/status strings — including raw {{path}} and {{error}} template placeholders — instead of the menu item labels, while the underlying actions still work correctly. Example: the item labeled "A telepítés nem sikerült" actually opens Discord (the action is right, the label is wrong). All possible states (success + failure + retry) are listed at once.

Environment

  • opencode version: 2.2.5 (desktop app ProductVersion 2.2.5.0, bundled CLI v2.2.5)
  • OS: Windows_NT 10.0.26300 (win32 x64)
  • Terminal: Unavailable: running in the desktop (Electron) app
  • Shell: C:\WINDOWS\system32\cmd.exe
  • Install/channel: latest (desktop installer + bundled CLI)
  • Active plugins: none found in config

Reproduction

  1. Windows machine where the opencode CLI is not on PATH (only the bundled resources/opencode-cli.exe exists); UI language: Hungarian.
  2. Open the desktop app's hamburger menu (top-left corner).
  3. Open the "CLI telepítése…" submenu.
  4. Observe the submenu labels (and the parent menu items).

Expected Behavior

Each menu item shows its own action label, e.g.:

  • CLI telepítve ide: <path> / Indítsa újra a terminált…
  • Discord megnyitása (or whatever the action really is)
  • Újra / Újraindítás

Actual Behavior

  • A CLI telepítve ide: {{path}} Indítsa újra a terminál… — raw {{path}} placeholder, concatenated status text
  • A telepítés nem sikerült — a status message used as a label; the item's action opens Discord
  • Nem sikerült telepíteni a CLI-t: {{error}} — raw {{error}} placeholder
  • Újra, Újraindítás — listed alongside the messages, so success and failure states appear simultaneously
  • Parent menu: Naplók exportálása.t… is truncated mid-word (ellipsis splits the string)

The actions point to the right place (verified: one item opens Discord); only the labels are wrong — the menu appears to be fed from the message/i18n catalog (strings with interpolation placeholders) instead of the menu-label keys.

Additional Context

  • Reproducible consistently (every time the menu is opened with the CLI missing from PATH).
  • Screenshot available on request (shows the menu + submenu exactly as described).
  • Searched existing issues: no match for raw {{...}} placeholders in menus, and no open Hungarian locale issues.
  • After placing an opencode.cmd shim on PATH (pointing at the bundled CLI), the "CLI telepítése…" entry may disappear on next app start (CLI detected) — the original repro requires the CLI to be absent from PATH.
  • No plugins, no recent config changes related to the menu.

Activity

  1. opencodejr commented on Nov 2, 2026

    @opencodejr

    Thanks for the detailed report. I can confirm this on 2.2.5, and it still happens on the latest dev (67139d6).

    The Hungarian translations for the desktop app's native menu are assigned to their menu items by position. The list is missing the first few entries, so every label moves up a few items. That is why Support Forum (which opens Discord) shows "A telepítés nem sikerült", OpenCode Documentation and Share Feedback show the CLI install messages with raw {{path}} / {{error}}, and Report a Bug shows "Újraindítás". The actions themselves are correct.

    Croatian, Icelandic and Lithuanian have the same problem; other languages are not affected. Until it's fixed, switching the app language to English (or any other unaffected language) shows the correct labels. The script below prints the labels each version resolves for a locale.

    Reproduction script (check-hu-menu.ts)
    // Shows which strings the desktop app's native menu gets for each locale.
    // Usage: bun /workspace/repro/check-hu-menu.ts <path to packages/app/src/runtime/i18n> [locale=hu]
    // The desktop menu/dialog strings are built in <locale>.ts as
    //   desktop.map((value, index) => [DESKTOP_NATIVE_KEYS[index], value])
    // so a list that is shorter than DESKTOP_NATIVE_KEYS shifts every label.
    const dir = process.argv[2] ?? "/workspace/repo/packages/app/src/runtime/i18n"
    const locale = process.argv[3] ?? "hu"
    const native = await import(`${dir}/desktop-native.ts`)
    const { dict } = await import(`${dir}/${locale}.ts`)
    const keys: string[] = native.DESKTOP_NATIVE_KEYS
    const en = native.DESKTOP_NATIVE_ENGLISH
    
    console.log(`DESKTOP_NATIVE_KEYS: ${keys.length}`)
    const show = [
      "desktop.menu.app",
      "desktop.menu.installCli",
      "desktop.menu.exportLogs",
      "desktop.menu.documentation",
      "desktop.menu.supportForum",
      "desktop.menu.shareFeedback",
      "desktop.menu.reportBug",
      "desktop.menu.ariaLabel",
      "desktop.cli.installed.title",
      "desktop.cli.failed.title",
    ]
    for (const k of show) console.log(`${k.padEnd(30)} en=${JSON.stringify(en[k])}\n${"".padEnd(30)} ${locale}=${JSON.stringify(dict[k])}`)
    
    // Check every locale that uses the positional list.
    console.log("\nLocales whose menu labels contain {{...}} placeholders the English label lacks:")
    for (const loc of native.DESKTOP_NATIVE_LOCALES) {
      let d: Record<string, string>
      try {
        d = (await import(`${dir}/${loc}.ts`)).dict
      } catch {
        continue
      }
      const bad = keys.filter((k) => k.startsWith("desktop.menu.") && /\{\{/.test(d[k] ?? "") && !/\{\{/.test(en[k]))
      const missing = keys.filter((k) => d[k] === undefined)
      if (bad.length) console.log(`  ${loc}: bad=${bad.join(",")} missingKeys=${missing.length}`)
    }

    Run it: bun check-hu-menu.ts

  2. askvittorio commented on Nov 2, 2026

    @askvittorio
    Author

    Investigation update — local analysis of the packaged app (hu-specific)

    Environment: desktop app 2.2.5.0 on Windows 10.0.26300, CLI not on PATH at the time (opencode only shipped as resources/opencode-cli.exe), UI language Hungarian.

    What we verified

    1. The English UI renders correct labels (tested by relaunching with OpenCode.exe --lang=en): parent menu shows Install CLI…, Settings, Reload Webview, Restart, Export Logs, New Session. So the label source resolves correctly in en.

    2. Actions are correct, labels are not (reporter): items in the "CLI telepítése…" submenu perform the right action — e.g. one opens the Discord invite (https://discord.com/invite/opencode from desktop.menu.supportForum) — while displaying unrelated status text.

    3. The submenu renders message templates as labels, with unsubstituted placeholders, and shows success and failure states at the same time:

      rendered (hu) matches key
      A CLI telepítve ide: {{path}} Indítsa újra a terminált az 'opencode2' parancs használatához. desktop.cli.installed.message
      A telepítés nem sikerült desktop.cli.failed.title
      Újra —
      Nem sikerült telepíteni a CLI-t: {{error}} desktop.cli.failed.message
      Újraindítás desktop.menu.restart

      {{path}} / {{error}} are never filled → state/message strings are being rendered in a label position.

    4. Bundle analysis (resources/app.asar, 225 MB):

      • Non-English locales ship as value arrays zipped with a canonical key array: Object.fromEntries([...values].map((t, n) => [e[n], t])) (keys imported from the main chunk).
      • We aligned the hu value array against the en key/value order:
        desktop.menu.installCli → CLI telepítése…, desktop.menu.reloadWebview → Webview újratöltése, desktop.menu.exportLogs → Naplók exportálása, desktop.menu.supportForum → Támogatási fórum, desktop.menu.documentation → OpenCode dokumentáció, desktop.menu.toggleTerminal → Terminál ki- és bekapcsolása, desktop.cli.installed.message → A CLI telepítve ide: {{path}}… — all pair correctly. The hu translation table itself is not shifted/missing entries (at least through the menu + cli block).
      • In the packaged code the only usage of desktop.cli.installed.message / desktop.cli.failed.* we could find is the native message box (Si.showMessageBox({type:'info'|'error', …}) in the CLI install-result handler) — no labelKey: desktop.cli.* menu reference was located, so the component that builds this submenu remains unidentified.
      • The native menu template is flat: {type:'item', labelKey:'desktop.menu.installCli', action:'app.installCli'} — no submenu there; the submenu shown in the screenshot comes from another component.
    5. Minor: a parent menu item renders truncated mid-word: Naplók exportálása.t….

    Questions for maintainers

    • Is the "Install CLI…" submenu state-driven (state messages rendered as menu items)? If so, the raw {{path}}/{{error}} templates are rendered without values, and success + failure states appear simultaneously.
    • Why does the rendering differ between en and hu if label resolution is key-based?

    Local workarounds tried

    • --lang=en → labels correct (per-launch).
    • PATH shim for the bundled CLI (opencode.cmd → resources/opencode-cli.exe) so the CLI is detected — may remove the "Install CLI…" entry after restart.
    • App restart + renderer reload did not fix the Hungarian labels → not a stale-cache issue.
    • Screenshot of the broken menu available on request from the reporter.
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