wavetermdev/waveterm · error

no window found with workspace ${data.workspaceid}

Error message

no window found with workspace ${data.workspaceid}

What it means

CpWshToRemote copies the local wsh binary to the remote host by piping it through `cat`. Before streaming, it opens the local file at wshLocalPath with os.Open; if that fails, this error wraps the open failure. The copy cannot proceed without a readable local wsh binary.

Source

Thrown at emain/emain-wsh.ts:24

import { RpcApi } from "@/app/store/wshclientapi";
import { Notification, net, safeStorage, shell } from "electron";
import { getResolvedUpdateChannel } from "emain/updater";
import { unamePlatform } from "./emain-platform";
import { getWebContentsByBlockId, webGetSelector } from "./emain-web";
import { createBrowserWindow, getWaveWindowById, getWaveWindowByWorkspaceId } from "./emain-window";

export class ElectronWshClientType extends WshClient {
    constructor() {
        super("electron");
    }

    async handle_webselector(rh: RpcResponseHelper, data: CommandWebSelectorData): Promise<string[]> {
        if (!data.tabid || !data.blockid || !data.workspaceid) {
            throw new Error("tabid and blockid are required");
        }
        const ww = getWaveWindowByWorkspaceId(data.workspaceid);
        if (ww == null) {
            throw new Error(`no window found with workspace ${data.workspaceid}`);
        }
        const wc = await getWebContentsByBlockId(ww, data.tabid, data.blockid);
        if (wc == null) {
            throw new Error(`no webcontents found with blockid ${data.blockid}`);
        }
        const rtn = await webGetSelector(wc, data.selector, data.opts);
        return rtn;
    }

    async handle_notify(rh: RpcResponseHelper, notificationOptions: WaveNotificationOptions) {
        new Notification({
            title: notificationOptions.title,
            body: notificationOptions.body,
            silent: notificationOptions.silent,
        }).show();
    }

    async handle_getupdatechannel(rh: RpcResponseHelper): Promise<string> {

View on GitHub (pinned to a4447c1563)

Solutions

  1. Check the file exists at wshLocalPath (stat it) and re-download/install wsh if missing
  2. Fix filesystem permissions on the file (`chmod +r`) or run as a user with access
  3. Check antivirus/Defender quarantine logs for the wsh binary
  4. Verify the code that populates wshLocalPath resolved the correct directory (wavebase config dir)

Example fix

// before
err := wslconn.CpWshToRemote(ctx, conn, wshLocalPath, remotePath)
// after
if _, err := os.Stat(wshLocalPath); err != nil {
    return fmt.Errorf("local wsh binary missing at %s, reinstall wsh first", wshLocalPath)
}
err := wslconn.CpWshToRemote(ctx, conn, wshLocalPath, remotePath)
Defensive patterns

Strategy: validation

Validate before calling

if fi, err := os.Stat(wshLocalPath); err != nil || fi.IsDir() {
    return fmt.Errorf("wsh binary missing at %s: reinstall wsh", wshLocalPath)
}

Try / catch

err := wslconn.CpWshToRemote(ctx, conn, wshLocalPath, remotePath)
if err != nil && strings.Contains(err.Error(), "cannot open local file") {
    // re-download the wsh binary and retry
}

Prevention

When it happens

Trigger: InstallWsh or UpdateWsh call CpWshToRemote and os.Open fails on wshLocalPath — file missing, path wrong, or permission denied.

Common situations: wsh binary was never downloaded to the expected local path; antivirus quarantined the binary; running under a user lacking read permission; partial update deleted the file mid-flight.

Understand the failure class

Background: "File not found" and ENOENT errors: why libraries can't find a file that should exist — this error's family across 50 libraries.

Related errors


AI-assisted analysis of wavetermdev/waveterm@a4447c1563 (2026-09-01). Data as JSON: /api/errors/5d922c61a7a2470c. Report an issue: GitHub.