xpipe-io/xpipe · error · BeaconClientException

Unknown launch request

Error message

Unknown launch request

What it means

TerminalLauncherManager.sshLaunchExchange() is invoked by a terminal child process to complete its pending launch request. It takes the most recent entry from the manager's entries map; if the map is empty, no launch request is known, so it throws BeaconClientException("Unknown launch request"). The library throws this to signal that the terminal process called back without any preceding request registration.

Source

Thrown at app/src/main/java/io/xpipe/app/terminal/TerminalLauncherManager.java:59

            var req = entries.get(request);
            if (req == null) {
                req = new TerminalLaunchRequest(request, processControl, config, directory);
                entries.put(request, req);
            } else {
                req.setResult(null);
            }

            req.setupRequestAsync();
        }
    }

    public static Path sshLaunchExchange() throws BeaconClientException, BeaconServerException {
        TerminalLaunchRequest last;
        synchronized (entries) {
            var all = entries.values().stream().toList();
            last = !all.isEmpty() ? all.getLast() : null;
            if (last == null) {
                throw new BeaconClientException("Unknown launch request");
            }
        }
        return last.waitForCompletion();
    }

    @SuppressWarnings("unused")
    public static boolean isCompletedSuccessfully(UUID request) {
        synchronized (entries) {
            var req = entries.get(request);
            return req.getResult() instanceof TerminalLaunchResult.ResultSuccess;
        }
    }

    public static void registerPid(UUID request, long pid) throws BeaconClientException {
        TerminalLaunchRequest req;
        synchronized (entries) {
            req = entries.get(request);
        }

View on GitHub (pinned to d85ca821ba)

Solutions

  1. Ensure the terminal is launched through the normal XPipe flow so a TerminalLaunchRequest is registered before the callback
  2. Re-initiate the connection from XPipe so a fresh launch request exists
  3. Avoid manually launching terminals that then call back into the beacon
  4. Check for races where entries are cleared/consumed before sshLaunchExchange runs

Example fix

// before
// terminal calls back without registration
TerminalLauncherManager.sshLaunchExchange(); // throws
// after
TerminalLauncherManager.submitRequest(entry, request); // register first
TerminalLauncherManager.sshLaunchExchange(); // now resolves
Defensive patterns

Strategy: retry

Validate before calling

boolean hasPendingRequest = TerminalLauncherManager.hasPendingEntries(); // only call sshLaunchExchange when true

Type guard

boolean known = !TerminalLauncherManager.getEntries().isEmpty();

Try / catch

try {
    TerminalLauncherManager.sshLaunchExchange();
} catch (BeaconClientException e) {
    if (e.getMessage().contains("Unknown launch request")) {
        // re-initiate launch from XPipe, then retry
    }
}

Prevention

When it happens

Trigger: sshLaunchExchange() called when the synchronized entries map is empty: no prior launch request was registered in this XPipe instance (e.g. terminal started manually, or state was lost/cleared before the terminal connected back).

Common situations: Opening a terminal session outside of XPipe's launch flow; XPipe restarted between spawning the terminal and the terminal's callback; concurrent requests raced so the last entry was consumed; stale terminal window reconnecting after the request was removed.

Understand the failure class

Background: 'Could not be found', 'does not exist', 'not found in database': the resource-not-found family when an ID, slug, key, or URI lookup comes back empty — this error's family across 20 libraries.

Related errors


AI-assisted analysis of xpipe-io/xpipe@d85ca821ba (2026-09-06). Data as JSON: /api/errors/6570121c24b4996c. Report an issue: GitHub.