Skip to content

Cmd+O ("Open in App") fails with No procedure found on path "external.openInApp" #5893

Closed as duplicate

Description

@bvidakovic

Where did this happen?

Desktop app (macOS)

Version

1.16.1 (stable) — Electron 40.8.5, macOS 26.5.2 (25F84), Apple Silicon (arm64)

What happened?

Pressing ⌘O ("Open in App") shows a toast:

Failed to open: No procedure found on path "external.openInApp"

Expected: the current project folder opens in the configured external editor.
Actual: the tRPC call is rejected at the routing layer before the mutation body runs, so nothing opens.

The external.openInApp procedure exists and is mounted in this build, so this isn't a missing-procedure regression — it's a router-targeting bug: the ⌘O action's IPC call reaches a tRPC router that doesn't carry the external sub-router. Reproduces on a clean launch of 1.16.1 (fresh processes, empty app cache). Full root-cause analysis below.

Steps to reproduce

  1. Launch Superset 1.16.1.
  2. Press ⌘O ("Open in App").
  3. See toast: Failed to open: No procedure found on path "external.openInApp".

Logs, screenshots, or recordings

No crash log is produced — the error is a tRPC routing rejection surfaced as a toast, not a crash.


Additional analysis (from inspecting app.asar)

external.openInApp is defined in the main app router only:

  • dist/main/index.js mounts external: createExternalRouter() unconditionally (alongside menu, settings, system, config, ports, …). createExternalRouter() exposes openUrl, openInFinder, openInApp, copyPath, copyText; openInApp takes { path, app, projectId? } → openPathInApp(path, app).

The other main-process routers do not carry external:

Router source has external / openInApp
dist/main/index.js (main app router) ✅ yes
dist/main/host-service.js ❌ no
dist/main/terminal-host.js ❌ no

The renderer references it via two clients: electronTrpc.external.openInApp (IPC → main router, has it) and electronTrpcClient.external.openInApp (→ host-service router, doesn't). So in the context where ⌘O fires, "Open in App" dispatches through the host-service client instead of the main IPC client, and the path can't resolve.

Suggested fixes:

  1. Route external.* (at least openInApp) through the main IPC client (electronTrpc), not electronTrpcClient; or
  2. Mount/forward the external router on the host-service router; or
  3. Guard/disable ⌘O when the focused context can't service external.openInApp, so it fails gracefully instead of erroring.

Activity

  1. github-actions commented on Jul 23, 2026

    @github-actions
    Contributor

    Triage: not reproducible on current main — appears already fixed since 1.16.1

    Thanks for the unusually detailed report — the root-cause mechanism you identified is correct, but the misrouting itself is no longer present on the current main branch. I traced every relevant seam:

    1. The external router is mounted on the main desktop router (and exposes openInApp).

    • apps/desktop/src/lib/trpc/routers/index.ts → external: createExternalRouter()
    • apps/desktop/src/lib/trpc/routers/external/index.ts defines openInApp({ path, app, projectId? })

    2. The host-service router does not carry external — confirming your analysis of why the error text appears when a call is misrouted:

    • packages/host-service/src/trpc/router/router.ts has no external key, so a call there would indeed throw No procedure found on path "external.openInApp".

    3. But no renderer code routes external.* through the host-service client.
    Every external.* call site (~20 of them) uses electronTrpc or electronTrpcClient — both main-process IPC clients (ipcLink, typed to the main AppRouter):

    • apps/desktop/src/renderer/lib/electron-trpc.ts (electronTrpc = createTRPCReact<AppRouter> over ipcLink)
    • apps/desktop/src/renderer/lib/trpc-client.ts (electronTrpcClient = createTRPCProxyClient<AppRouter> over ipcLink)

    There are no getHostServiceClientByUrl(...).external.* calls anywhere in the renderer.

    4. The dashboard ⌘O handler is correctly wired and guarded (which covers your suggested fixes #1 and #3):

    • V2OpenInMenuButton calls electronTrpc.external.openInApp (main IPC) and registers useHotkey("OPEN_IN_APP", …).
    • Its wrapper V2WorkspaceOpenInButton only renders it when isLocalWorkspace (workspace.hostId === machineId), so the ⌘O hotkey isn't even registered for remote/host workspaces.
    • The command-palette "Open in…" provider (renderer/commandPalette/modules/openIn/commands.ts) likewise resolves the path via the host service but performs the open via electronTrpcClient.external.openInApp (main IPC), and returns no commands for remote workspaces.

    Why no test/PR: A headless bun:test reproduction would need the reported misroute to exist in source, but on current main every external.openInApp path targets the main-process router that mounts the procedure, and remote workspaces are guarded so the shortcut isn't bound there. I couldn't construct a failing reproduction, so I'm not opening a PR.

    This strongly suggests the bug was fixed after 1.16.1. Could you confirm whether the latest build still reproduces? If it does, the most useful next detail would be which window/route you fire ⌘O from and whether that workspace is local or on a remote host — that would tell us which code path (and client) is actually servicing the shortcut in your build.

  2. bvidakovic commented on Jul 23, 2026

    @bvidakovic
    Author

    Thanks for the thorough trace — really helpful. Answering your two questions, then what I can confirm from the shipped 1.16.1 bundle, since the picture there is a bit different from main.

    Which window/route, local or remote?
    Local project dashboard, project living on this Mac — not a remote/host workspace. So the isLocalWorkspace guard is satisfied; this is the "should-work" local path, which is what makes the repro interesting.

    Does the latest build still reproduce?
    I'm on 1.16.1, which is the current stable release — the fix you traced appears to be on main/unreleased. Repro is on a fully clean relaunch (all processes killed and restarted, crash-reporter reports _version=1.16.1, app Cache/Code Cache ≈ empty). Haven't tried the Canary yet.

    What the shipped 1.16.1 renderer does on that dashboard path (dist/renderer/assets/page-CAuCet-l.js):

    • V2OpenInMenuButton registers useHotkey("OPEN_IN_APP", handleOpenInEditor).
    • handleOpenInEditor → openInApp.mutate({ path: worktreePath, app: resolvedApp }).
    • const openInApp = electronTrpc.external.openInApp.useMutation({ onError: e => toast.error(\Failed to open: ${e.message}`) })— thatonError` is exactly the toast I saw.
    • Wrapper V2WorkspaceOpenInButton computes isLocalWorkspace = workspace.hostId === machineId (guard present), and the sibling openFileInEditor even has the explicit "Can't open remote workspace paths in an external editor" check.

    So in 1.16.1 the local ⌘O path already dispatches through electronTrpc (the main-process IPC client) — the same client you verified reaches the main AppRouter that mounts external. On the main side, dist/main/index.js does mount external: createExternalRouter() unconditionally; dist/main/host-service.js and dist/main/terminal-host.js do not.

    Net: on 1.16.1 the electron-trpc IPC endpoint servicing the dashboard window appears not to expose the external router even though the root router object includes it — i.e. it looks like a main-side client↔router binding issue rather than the renderer misrouting you've already fixed. Does that line up with any main-process handler/router wiring change that landed after 1.16.1?

    One caveat I can't rule out from the asar alone: if released builds render the desktop UI from a remotely-served bundle rather than the local dist/renderer, the actually-running client binding could differ from what's in the package.

    Happy to pull the tRPC error.data (code / path / httpStatus) from the renderer devtools if that'd help pin it down — just say the word.

  3. david-velasquez-v commented on Jul 23, 2026

    @david-velasquez-v

    I am also having this issue, so either the fix hasn't shipped or the triage is incorrect.

    As a note this seems a duplicate of #5850

  4. Kitenite commented on Jul 28, 2026

    @Kitenite
    Member

    Merged this with #5903 into one ticket in our tracker (SUPER-1598). Thanks for the router analysis, it points right at the mismatch between the main-process and host-service tRPC clients.

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions