xpipe-io/xpipe · error · BeaconClientException
Unsupported mode: " + msg.getMode().getDisplayName() + "…
Error message
Unsupported mode: " + msg.getMode().getDisplayName() + ". Supported: " + String.join(", ", supportedModeIds) What it means
The daemon's mode-switch endpoint received a DaemonMode whose target AppOperationMode is not supported in this environment. XPipe builds modes conditionally (e.g. headless vs desktop variants), so a mode id that exists on one installation may not be available or startable on another. The error lists all currently supported mode ids to guide the client.
Solutions
- Read the 'Supported: ...' list from the error and only request one of those mode ids
- Install the XPipe variant that includes the desired operation mode (e.g. full desktop package instead of headless)
- Update the client library so its DaemonMode enum matches the daemon's supported modes
- Skip the mode-switch call on headless systems and keep the default mode
Example fix
// before
client.setMode(DaemonMode.GUI);
// after
if (supportedModes.contains("gui")) {
client.setMode(DaemonMode.GUI);
} else {
logger.warn("GUI mode unsupported on this daemon; staying in " + currentMode);
} Defensive patterns
Strategy: validation
Validate before calling
Set<String> supported = fetchSupportedModes();
if (!supported.contains(requestedMode.getId())) {
throw new IllegalArgumentException("Mode " + requestedMode + " unsupported; supported: " + supported);
} Try / catch
try {
client.setMode(mode);
} catch (BeaconClientException e) {
if (e.getMessage().startsWith("Unsupported mode")) {
logger.warn("Falling back to current mode: " + e.getMessage());
} else throw e;
} Prevention
- Parse the 'Supported:' list from the error message
- Detect headless/desktop builds before sending mode-switch requests
- Keep client mode enum in sync with the daemon version
When it happens
Trigger: Posting to DaemonModeExchange with msg.getMode() mapping to an AppOperationMode whose isSupported() is false — e.g. requesting 'desktop' mode on a headless server build, or a build lacking a specific operation-mode module.
Common situations: Switching the daemon to background/desktop mode from a client on a machine whose XPipe package was compiled without that mode; CI/headless containers receiving the same requests used on desktop machines; stale clients sending mode ids removed in a newer daemon.
Understand the failure class
Background: Invalid enum value errors: "Unknown type", "Invalid scope", "must be one of" — when a string is not on the library's allowed list — this error's family across 23 libraries.
Related errors
- Authentication failed
- Cannot delete category: " + cat.getName()
- Directory " + msg.getPath().getParent() + " does not exist
- File " + msg.getPath() + " does not exist
- File path " + msg.getPath() + " is not absolute
AI-assisted analysis of xpipe-io/xpipe@d85ca821ba (2026-09-06).
Data as JSON: /api/errors/540526fd3ff8e0e7.
Report an issue: GitHub.
Appendix: source
Thrown at app/src/main/java/io/xpipe/app/beacon/api/DaemonModeExchange.java:25
import com.sun.net.httpserver.HttpExchange;
import lombok.Builder;
import lombok.NonNull;
import lombok.Value;
import lombok.extern.jackson.Jacksonized;
public class DaemonModeExchange extends BeaconInterface<DaemonModeExchange.Request> {
@Override
public String getPath() {
return "/daemon/mode";
}
@Override
public Object handle(HttpExchange exchange, Request msg) throws BeaconClientException {
var mode = AppOperationMode.map(msg.getMode());
if (!mode.isSupported()) {
throw new BeaconClientException("Unsupported mode: " + msg.getMode().getDisplayName()
+ ". Supported: "
+ String.join(
", ",
AppOperationMode.getAll().stream()
.filter(AppOperationMode::isSupported)
.map(AppOperationMode::getId)
.toList()));
}
AppOperationMode.switchToSyncIfPossible(mode);
return Response.builder().usedMode(msg.getMode()).build();
}
@Override
public boolean requiresEnabledApi() {
return false;
}
View on GitHub (pinned to d85ca821ba)